From b892db9976b3bc6cf0def434d0cc1fb7d746c469 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 9 Feb 2021 17:03:06 +0300 Subject: [PATCH] vm: add instruction correctness check See neo-project/neo-vm#392. --- pkg/vm/context.go | 4 ++++ pkg/vm/opcode/opcode.go | 6 ++++++ pkg/vm/opcode/opcode_test.go | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/pkg/vm/context.go b/pkg/vm/context.go index dcbee69ab..af20090cc 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -3,6 +3,7 @@ package vm import ( "encoding/binary" "errors" + "fmt" "math/big" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" @@ -109,6 +110,9 @@ func (c *Context) Next() (opcode.Opcode, []byte, error) { var instrbyte = c.prog[c.ip] instr := opcode.Opcode(instrbyte) + if !opcode.IsValid(instr) { + return instr, nil, fmt.Errorf("incorrect opcode %s", instr.String()) + } c.nextip++ var numtoread int diff --git a/pkg/vm/opcode/opcode.go b/pkg/vm/opcode/opcode.go index f2fcca417..25e759a31 100644 --- a/pkg/vm/opcode/opcode.go +++ b/pkg/vm/opcode/opcode.go @@ -219,3 +219,9 @@ const ( ISTYPE Opcode = 0xD9 CONVERT Opcode = 0xDB ) + +// IsValid returns true if the opcode passed is valid (defined in the VM). +func IsValid(op Opcode) bool { + _, ok := _Opcode_map[op] // We rely on stringer here, it has a map anyway. + return ok +} diff --git a/pkg/vm/opcode/opcode_test.go b/pkg/vm/opcode/opcode_test.go index f0f5a0451..89514532a 100644 --- a/pkg/vm/opcode/opcode_test.go +++ b/pkg/vm/opcode/opcode_test.go @@ -28,3 +28,10 @@ func TestFromString(t *testing.T) { require.NoError(t, err) require.Equal(t, MUL, op) } + +func TestIsValid(t *testing.T) { + require.True(t, IsValid(ADD)) + require.True(t, IsValid(CONVERT)) + require.False(t, IsValid(0xff)) + require.False(t, IsValid(0xa5)) +}