mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
90705e37e9
Retun an error if the serialized NEF size exceeds stackitem.MaxSize. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
192 lines
5.1 KiB
Go
192 lines
5.1 KiB
Go
package nef
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/nspcc-dev/neo-go/internal/random"
|
|
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestEncodeDecodeBinary(t *testing.T) {
|
|
script := []byte{12, 32, 84, 35, 14}
|
|
expected := &File{
|
|
Header: Header{
|
|
Magic: Magic,
|
|
Compiler: "best compiler version 1",
|
|
},
|
|
Tokens: []MethodToken{{
|
|
Hash: random.Uint160(),
|
|
Method: "method",
|
|
ParamCount: 3,
|
|
HasReturn: true,
|
|
CallFlag: callflag.WriteStates,
|
|
}},
|
|
Script: script,
|
|
}
|
|
|
|
t.Run("invalid Magic", func(t *testing.T) {
|
|
expected.Header.Magic = 123
|
|
checkDecodeError(t, expected)
|
|
})
|
|
|
|
t.Run("invalid checksum", func(t *testing.T) {
|
|
expected.Header.Magic = Magic
|
|
expected.Checksum = 123
|
|
checkDecodeError(t, expected)
|
|
})
|
|
|
|
t.Run("zero-length script", func(t *testing.T) {
|
|
expected.Script = make([]byte, 0)
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
checkDecodeError(t, expected)
|
|
})
|
|
|
|
t.Run("invalid script length", func(t *testing.T) {
|
|
newScript := make([]byte, stackitem.MaxSize+1)
|
|
expected.Script = newScript
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
checkDecodeError(t, expected)
|
|
})
|
|
t.Run("invalid tokens list", func(t *testing.T) {
|
|
expected.Script = script
|
|
expected.Tokens[0].Method = "_reserved"
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
checkDecodeError(t, expected)
|
|
})
|
|
|
|
t.Run("positive", func(t *testing.T) {
|
|
expected.Script = script
|
|
expected.Tokens[0].Method = "method"
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
expected.Header.Magic = Magic
|
|
testserdes.EncodeDecodeBinary(t, expected, &File{})
|
|
})
|
|
t.Run("positive with empty tokens", func(t *testing.T) {
|
|
expected.Script = script
|
|
// Check `Tokens` won't be deserialized to `nil`. We expect them to be non-nil slice in the related code.
|
|
expected.Tokens = []MethodToken{}
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
expected.Header.Magic = Magic
|
|
testserdes.EncodeDecodeBinary(t, expected, &File{})
|
|
})
|
|
t.Run("invalid reserved bytes", func(t *testing.T) {
|
|
expected.Script = script
|
|
expected.Tokens = expected.Tokens[:0]
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
bytes, err := testserdes.EncodeBinary(expected)
|
|
require.NoError(t, err)
|
|
|
|
sz := io.GetVarSize(&expected.Header)
|
|
bytes[sz] = 1
|
|
err = testserdes.DecodeBinary(bytes, new(File))
|
|
require.ErrorIs(t, err, errInvalidReserved)
|
|
|
|
bytes[sz] = 0
|
|
bytes[sz+3] = 1
|
|
err = testserdes.DecodeBinary(bytes, new(File))
|
|
require.ErrorIs(t, err, errInvalidReserved)
|
|
})
|
|
}
|
|
|
|
func checkDecodeError(t *testing.T, expected *File) {
|
|
bytes, err := testserdes.EncodeBinary(expected)
|
|
require.NoError(t, err)
|
|
require.Error(t, testserdes.DecodeBinary(bytes, &File{}))
|
|
}
|
|
|
|
func TestBytesFromBytes(t *testing.T) {
|
|
script := []byte{12, 32, 84, 35, 14}
|
|
expected := File{
|
|
Header: Header{
|
|
Magic: Magic,
|
|
Compiler: "best compiler version 1",
|
|
},
|
|
Tokens: []MethodToken{{
|
|
Hash: random.Uint160(),
|
|
Method: "someMethod",
|
|
ParamCount: 3,
|
|
HasReturn: true,
|
|
CallFlag: callflag.WriteStates,
|
|
}},
|
|
Script: script,
|
|
}
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
|
|
bytes, err := expected.Bytes()
|
|
require.NoError(t, err)
|
|
actual, err := FileFromBytes(bytes)
|
|
require.NoError(t, err)
|
|
require.Equal(t, expected, actual)
|
|
}
|
|
|
|
func TestNewFileFromBytesLimits(t *testing.T) {
|
|
expected := File{
|
|
Header: Header{
|
|
Magic: Magic,
|
|
Compiler: "best compiler version 1",
|
|
},
|
|
Tokens: []MethodToken{{
|
|
Hash: random.Uint160(),
|
|
Method: "someMethod",
|
|
ParamCount: 3,
|
|
HasReturn: true,
|
|
CallFlag: callflag.WriteStates,
|
|
}},
|
|
Script: make([]byte, stackitem.MaxSize-100),
|
|
}
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
|
|
bytes, err := expected.BytesLong()
|
|
require.NoError(t, err)
|
|
_, err = FileFromBytes(bytes)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "invalid NEF file size")
|
|
}
|
|
|
|
func TestMarshalUnmarshalJSON(t *testing.T) {
|
|
expected := &File{
|
|
Header: Header{
|
|
Magic: Magic,
|
|
Compiler: "test.compiler-test.ver",
|
|
},
|
|
Tokens: []MethodToken{{
|
|
Hash: util.Uint160{0x12, 0x34, 0x56, 0x78, 0x91, 0x00},
|
|
Method: "someMethod",
|
|
ParamCount: 3,
|
|
HasReturn: true,
|
|
CallFlag: callflag.WriteStates,
|
|
}},
|
|
Script: []byte{1, 2, 3, 4},
|
|
}
|
|
expected.Checksum = expected.CalculateChecksum()
|
|
|
|
data, err := json.Marshal(expected)
|
|
require.NoError(t, err)
|
|
require.JSONEq(t, `{
|
|
"magic":`+strconv.FormatUint(uint64(Magic), 10)+`,
|
|
"compiler": "test.compiler-test.ver",
|
|
"source": "",
|
|
"tokens": [
|
|
{
|
|
"hash": "0x`+expected.Tokens[0].Hash.StringLE()+`",
|
|
"method": "someMethod",
|
|
"paramcount": 3,
|
|
"hasreturnvalue": true,
|
|
"callflags": "`+expected.Tokens[0].CallFlag.String()+`"
|
|
}
|
|
],
|
|
"script": "`+base64.StdEncoding.EncodeToString(expected.Script)+`",
|
|
"checksum":`+strconv.FormatUint(uint64(expected.Checksum), 10)+`}`, string(data))
|
|
|
|
actual := new(File)
|
|
require.NoError(t, json.Unmarshal(data, actual))
|
|
require.Equal(t, expected, actual)
|
|
}
|