core/vm: no more recursive errors

This commit is contained in:
Marius van der Wijden 2024-09-06 12:21:30 +02:00
parent cdae48c452
commit 5a1acc4a07
2 changed files with 11 additions and 2 deletions

View file

@ -89,7 +89,7 @@ type Container struct {
ContainerSections []*Container ContainerSections []*Container
ContainerCode [][]byte ContainerCode [][]byte
Data []byte Data []byte
DataSize int // might be less than len(Data) DataSize int // might be more than len(Data)
} }
// FunctionMetadata is an EOF function signature. // FunctionMetadata is an EOF function signature.
@ -292,7 +292,10 @@ func (c *Container) unmarshalSubContainer(b []byte, isInitcode bool, topLevel bo
c := new(Container) c := new(Container)
end := min(idx+size, len(b)) end := min(idx+size, len(b))
if err := c.unmarshalSubContainer(b[idx:end], isInitcode, false); err != nil { if err := c.unmarshalSubContainer(b[idx:end], isInitcode, false); err != nil {
return fmt.Errorf("%w for section %d", err, i) if topLevel {
return fmt.Errorf("%w in sub container %d", err, i)
}
return err
} }
container = append(container, c) container = append(container, c)
containerCode = append(containerCode, b[idx:end]) containerCode = append(containerCode, b[idx:end])

View file

@ -120,9 +120,15 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable,
if arg >= len(container.Types) { if arg >= len(container.Types) {
return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidSectionArgument, arg, len(container.Types), i) return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidSectionArgument, arg, len(container.Types), i)
} }
// TODO check if that is actually a problem
// JUMPF operand must point to a code section with equal or fewer number of outputs as the section in which it resides, or to a section with 0x80 as outputs (non-returning)
if container.Types[arg].Output > container.Types[section].Output {
return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidSectionArgument, arg, len(container.Types), i)
}
visitedCode[arg] = struct{}{} visitedCode[arg] = struct{}{}
case op == DATALOADN: case op == DATALOADN:
arg, _ := parseUint16(code[i+1:]) arg, _ := parseUint16(code[i+1:])
// TODO why are we checking this? We should just pad
if arg+32 > len(container.Data) { if arg+32 > len(container.Data) {
return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidDataloadNArgument, arg, len(container.Data), i) return nil, fmt.Errorf("%w: arg %d, last %d, pos %d", ErrInvalidDataloadNArgument, arg, len(container.Data), i)
} }