From 9331fe28e89dd22820ee8999d11aa2938c5198cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 3 Dec 2021 11:04:54 +0100 Subject: [PATCH] core/vm: fill gaps in jump table with opUndefined (#24031) --- core/vm/instructions.go | 4 ++++ core/vm/interpreter.go | 3 --- core/vm/jump_table.go | 11 ++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index cc225e484..1e91ff255 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -801,6 +801,10 @@ func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b return ret, ErrExecutionReverted } +func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])} +} + func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { return nil, errStopToken } diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 99257d57a..a4c54b1fb 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -193,9 +193,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // enough stack items available to perform the operation. op = contract.GetOp(pc) operation := in.cfg.JumpTable[op] - if operation == nil { - return nil, &ErrInvalidOpCode{opcode: op} - } // Validate stack if sLen := stack.len(); sLen < operation.minStack { return nil, &ErrStackUnderflow{stackLen: sLen, required: operation.minStack} diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 676cfc060..bb559b594 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -200,7 +200,7 @@ func newHomesteadInstructionSet() JumpTable { // newFrontierInstructionSet returns the frontier instructions // that can be executed during the frontier phase. func newFrontierInstructionSet() JumpTable { - return JumpTable{ + tbl := JumpTable{ STOP: { execute: opStop, constantGas: 0, @@ -1002,4 +1002,13 @@ func newFrontierInstructionSet() JumpTable { maxStack: maxStack(1, 0), }, } + + // Fill all unassigned slots with opUndefined. + for i, entry := range tbl { + if entry == nil { + tbl[i] = &operation{execute: opUndefined, maxStack: maxStack(0, 0)} + } + } + + return tbl }