diff --git a/core/vm/errors.go b/core/vm/errors.go index f9eb79507c31..f6b156a02e38 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -23,6 +23,9 @@ import ( // List evm execution errors var ( + // ErrInvalidSubroutineEntry means that a BEGINSUB was reached via iteration, + // as opposed to from a JUMPSUB instruction + ErrInvalidSubroutineEntry = errors.New("invalid subroutine entry") ErrOutOfGas = errors.New("out of gas") ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") ErrDepth = errors.New("max call depth exceeded") diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 32e06fece695..7f81a1bc3582 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -665,7 +665,7 @@ func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ( } func opBeginSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { - return nil, nil + return nil, ErrInvalidSubroutineEntry } func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { @@ -681,7 +681,7 @@ func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([ return nil, ErrInvalidJump } callContext.rstack.push(*pc) - *pc = posU64 + *pc = posU64+1 interpreter.intPool.put(pos) return nil, nil } diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 36c3fc57864e..786cfa2a3c0c 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -538,7 +538,7 @@ func TestEipExampleCases(t *testing.T) { prettyPrint("This should fail at first opcode, due to shallow `return_stack`", code) } - { // First eip testcase + { code := []byte{ byte(vm.PUSH1), 5, // Jump past the subroutine byte(vm.JUMP), @@ -553,4 +553,13 @@ func TestEipExampleCases(t *testing.T) { "and not exit with error", code) } + { + code := []byte{ + byte(vm.BEGINSUB), + byte(vm.RETURNSUB), + byte(vm.STOP), + } + prettyPrint("In this example, the code 'walks' into a subroutine, which is not "+ + "allowed, and causes an error", code) + } }