forked from TrueCloudLab/neoneo-go
vm: restrict comparable ByteArray length
MaxByteArrayComparableSize should equals to 65535.
This commit is contained in:
parent
e550608ecd
commit
1f9b92c295
2 changed files with 51 additions and 13 deletions
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
@ -16,14 +17,17 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MaxBigIntegerSizeBits is the maximum size of BigInt item in bits.
|
const (
|
||||||
const MaxBigIntegerSizeBits = 32 * 8
|
// MaxBigIntegerSizeBits is the maximum size of BigInt item in bits.
|
||||||
|
MaxBigIntegerSizeBits = 32 * 8
|
||||||
// MaxArraySize is the maximum array size allowed in the VM.
|
// MaxArraySize is the maximum array size allowed in the VM.
|
||||||
const MaxArraySize = 1024
|
MaxArraySize = 1024
|
||||||
|
// MaxSize is the maximum item size allowed in the VM.
|
||||||
// MaxSize is the maximum item size allowed in the VM.
|
MaxSize = 1024 * 1024
|
||||||
const MaxSize = 1024 * 1024
|
// MaxByteArrayComparableSize is the maximum allowed length of ByteArray for Equals method.
|
||||||
|
// It is set to be the maximum uint16 value.
|
||||||
|
MaxByteArrayComparableSize = math.MaxUint16
|
||||||
|
)
|
||||||
|
|
||||||
// Item represents the "real" value that is pushed on the stack.
|
// Item represents the "real" value that is pushed on the stack.
|
||||||
type Item interface {
|
type Item interface {
|
||||||
|
@ -46,7 +50,10 @@ type Item interface {
|
||||||
Convert(Type) (Item, error)
|
Convert(Type) (Item, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var errInvalidConversion = errors.New("invalid conversion type")
|
var (
|
||||||
|
errInvalidConversion = errors.New("invalid conversion type")
|
||||||
|
errExceedingMaxComparableSize = errors.New("the operand exceeds the maximum comparable size")
|
||||||
|
)
|
||||||
|
|
||||||
// Make tries to make appropriate stack item from provided value.
|
// Make tries to make appropriate stack item from provided value.
|
||||||
// It will panic if it's not possible.
|
// It will panic if it's not possible.
|
||||||
|
@ -536,13 +543,22 @@ func (i *ByteArray) TryInteger() (*big.Int, error) {
|
||||||
|
|
||||||
// Equals implements Item interface.
|
// Equals implements Item interface.
|
||||||
func (i *ByteArray) Equals(s Item) bool {
|
func (i *ByteArray) Equals(s Item) bool {
|
||||||
|
if len(i.value) > MaxByteArrayComparableSize {
|
||||||
|
panic(errExceedingMaxComparableSize)
|
||||||
|
}
|
||||||
if i == s {
|
if i == s {
|
||||||
return true
|
return true
|
||||||
} else if s == nil {
|
} else if s == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val, ok := s.(*ByteArray)
|
val, ok := s.(*ByteArray)
|
||||||
return ok && bytes.Equal(i.value, val.value)
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(val.value) > MaxByteArrayComparableSize {
|
||||||
|
panic(errExceedingMaxComparableSize)
|
||||||
|
}
|
||||||
|
return bytes.Equal(i.value, val.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dup implements Item interface.
|
// Dup implements Item interface.
|
||||||
|
|
|
@ -143,6 +143,7 @@ var equalsTestCases = map[string][]struct {
|
||||||
item1 Item
|
item1 Item
|
||||||
item2 Item
|
item2 Item
|
||||||
result bool
|
result bool
|
||||||
|
panics bool
|
||||||
}{
|
}{
|
||||||
"struct": {
|
"struct": {
|
||||||
{
|
{
|
||||||
|
@ -251,6 +252,21 @@ var equalsTestCases = map[string][]struct {
|
||||||
item2: Make([]byte{1, 2, 3}),
|
item2: Make([]byte{1, 2, 3}),
|
||||||
result: true,
|
result: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
item1: NewByteArray(make([]byte, MaxByteArrayComparableSize+1)),
|
||||||
|
item2: NewByteArray([]byte{1, 2, 3}),
|
||||||
|
panics: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item1: NewByteArray([]byte{1, 2, 3}),
|
||||||
|
item2: NewByteArray(make([]byte, MaxByteArrayComparableSize+1)),
|
||||||
|
panics: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item1: NewByteArray(make([]byte, MaxByteArrayComparableSize+1)),
|
||||||
|
item2: NewByteArray(make([]byte, MaxByteArrayComparableSize+1)),
|
||||||
|
panics: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"array": {
|
"array": {
|
||||||
{
|
{
|
||||||
|
@ -350,9 +366,15 @@ func TestEquals(t *testing.T) {
|
||||||
for name, testBatch := range equalsTestCases {
|
for name, testBatch := range equalsTestCases {
|
||||||
for _, testCase := range testBatch {
|
for _, testCase := range testBatch {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
assert.Equal(t, testCase.result, testCase.item1.Equals(testCase.item2))
|
if testCase.panics {
|
||||||
// Reference equals
|
assert.Panics(t, func() {
|
||||||
assert.Equal(t, true, testCase.item1.Equals(testCase.item1))
|
testCase.item1.Equals(testCase.item2)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
assert.Equal(t, testCase.result, testCase.item1.Equals(testCase.item2))
|
||||||
|
// Reference equals
|
||||||
|
assert.Equal(t, true, testCase.item1.Equals(testCase.item1))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue