forked from TrueCloudLab/neoneo-go
Merge pull request #1346 from nspcc-dev/string-tryboolean
Fail converting long strings to boolean
This commit is contained in:
commit
e5813ae8cd
9 changed files with 77 additions and 46 deletions
|
@ -1514,7 +1514,11 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
}
|
}
|
||||||
resEl := vm.Estack().Pop()
|
resEl := vm.Estack().Pop()
|
||||||
if resEl != nil {
|
if resEl != nil {
|
||||||
if !resEl.Bool() {
|
res, err := resEl.Item().TryBool()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%w: invalid return value", ErrVerificationFailed)
|
||||||
|
}
|
||||||
|
if !res {
|
||||||
return fmt.Errorf("%w: invalid signature", ErrVerificationFailed)
|
return fmt.Errorf("%w: invalid signature", ErrVerificationFailed)
|
||||||
}
|
}
|
||||||
if vm.Estack().Len() != 0 {
|
if vm.Estack().Len() != 0 {
|
||||||
|
|
|
@ -401,6 +401,17 @@ func TestVerifyHashAgainstScript(t *testing.T) {
|
||||||
err := bc.verifyHashAgainstScript(hash.Hash160(verif), w, ic, false, gas)
|
err := bc.verifyHashAgainstScript(hash.Hash160(verif), w, ic, false, gas)
|
||||||
require.True(t, errors.Is(err, ErrVerificationFailed))
|
require.True(t, errors.Is(err, ErrVerificationFailed))
|
||||||
})
|
})
|
||||||
|
t.Run("BadResult", func(t *testing.T) {
|
||||||
|
verif := make([]byte, 66)
|
||||||
|
verif[0] = byte(opcode.PUSHDATA1)
|
||||||
|
verif[1] = 64
|
||||||
|
w := &transaction.Witness{
|
||||||
|
InvocationScript: []byte{byte(opcode.NOP)},
|
||||||
|
VerificationScript: verif,
|
||||||
|
}
|
||||||
|
err := bc.verifyHashAgainstScript(hash.Hash160(verif), w, ic, false, gas)
|
||||||
|
require.True(t, errors.Is(err, ErrVerificationFailed))
|
||||||
|
})
|
||||||
t.Run("TooManyResults", func(t *testing.T) {
|
t.Run("TooManyResults", func(t *testing.T) {
|
||||||
verif := []byte{byte(opcode.NOP)}
|
verif := []byte{byte(opcode.NOP)}
|
||||||
w := &transaction.Witness{
|
w := &transaction.Witness{
|
||||||
|
|
|
@ -577,8 +577,12 @@ func compareContractStates(t *testing.T, expected *state.Contract, actual stacki
|
||||||
require.Equal(t, 4, len(act))
|
require.Equal(t, 4, len(act))
|
||||||
require.Equal(t, expected.Script, act[0].Value().([]byte))
|
require.Equal(t, expected.Script, act[0].Value().([]byte))
|
||||||
require.Equal(t, expectedManifest, act[1].Value().([]byte))
|
require.Equal(t, expectedManifest, act[1].Value().([]byte))
|
||||||
require.Equal(t, expected.HasStorage(), act[2].Bool())
|
hasstorage, err := act[2].TryBool()
|
||||||
require.Equal(t, expected.IsPayable(), act[3].Bool())
|
require.NoError(t, err)
|
||||||
|
ispayable, err := act[3].TryBool()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expected.HasStorage(), hasstorage)
|
||||||
|
require.Equal(t, expected.IsPayable(), ispayable)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContractUpdate(t *testing.T) {
|
func TestContractUpdate(t *testing.T) {
|
||||||
|
|
|
@ -42,7 +42,10 @@ func (c *candidate) fromStackItem(item stackitem.Item) *candidate {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
c.Registered = arr[0].Bool()
|
c.Registered, err = arr[0].TryBool()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
c.Votes = *vs
|
c.Votes = *vs
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,8 +191,8 @@ func (c *Context) Dup() stackitem.Item {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements stackitem.Item interface.
|
// TryBool implements stackitem.Item interface.
|
||||||
func (c *Context) Bool() bool { panic("can't convert Context to Bool") }
|
func (c *Context) TryBool() (bool, error) { panic("can't convert Context to Bool") }
|
||||||
|
|
||||||
// TryBytes implements stackitem.Item interface.
|
// TryBytes implements stackitem.Item interface.
|
||||||
func (c *Context) TryBytes() ([]byte, error) {
|
func (c *Context) TryBytes() ([]byte, error) {
|
||||||
|
|
|
@ -54,8 +54,8 @@ func (c *exceptionHandlingContext) Dup() stackitem.Item {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements stackitem.Item interface.
|
// TryBool implements stackitem.Item interface.
|
||||||
func (c *exceptionHandlingContext) Bool() bool {
|
func (c *exceptionHandlingContext) TryBool() (bool, error) {
|
||||||
panic("can't convert exceptionHandlingContext to Bool")
|
panic("can't convert exceptionHandlingContext to Bool")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,9 +80,14 @@ func (e *Element) BigInt() *big.Int {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool converts an underlying value of the element to a boolean.
|
// Bool converts an underlying value of the element to a boolean if it's
|
||||||
|
// possible to do so, it will panic otherwise.
|
||||||
func (e *Element) Bool() bool {
|
func (e *Element) Bool() bool {
|
||||||
return e.value.Bool()
|
b, err := e.value.TryBool()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes attempts to get the underlying value of the element as a byte array.
|
// Bytes attempts to get the underlying value of the element as a byte array.
|
||||||
|
|
|
@ -31,8 +31,8 @@ type Item interface {
|
||||||
Value() interface{}
|
Value() interface{}
|
||||||
// Dup duplicates current Item.
|
// Dup duplicates current Item.
|
||||||
Dup() Item
|
Dup() Item
|
||||||
// Bool converts Item to a boolean value.
|
// TryBool converts Item to a boolean value.
|
||||||
Bool() bool
|
TryBool() (bool, error)
|
||||||
// TryBytes converts Item to a byte slice.
|
// TryBytes converts Item to a byte slice.
|
||||||
TryBytes() ([]byte, error)
|
TryBytes() ([]byte, error)
|
||||||
// TryInteger converts Item to an integer.
|
// TryInteger converts Item to an integer.
|
||||||
|
@ -155,7 +155,11 @@ func convertPrimitive(item Item, typ Type) (Item, error) {
|
||||||
}
|
}
|
||||||
return NewByteArray(b), nil
|
return NewByteArray(b), nil
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(item.Bool()), nil
|
b, err := item.TryBool()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewBool(b), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidConversion
|
return nil, errInvalidConversion
|
||||||
}
|
}
|
||||||
|
@ -210,8 +214,8 @@ func (i *Struct) Dup() Item {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *Struct) Bool() bool { return true }
|
func (i *Struct) TryBool() (bool, error) { return true, nil }
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
func (i *Struct) TryBytes() ([]byte, error) {
|
func (i *Struct) TryBytes() ([]byte, error) {
|
||||||
|
@ -255,7 +259,7 @@ func (i *Struct) Convert(typ Type) (Item, error) {
|
||||||
copy(arr, i.value)
|
copy(arr, i.value)
|
||||||
return NewArray(arr), nil
|
return NewArray(arr), nil
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(i.Bool()), nil
|
return NewBool(true), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidConversion
|
return nil, errInvalidConversion
|
||||||
}
|
}
|
||||||
|
@ -296,8 +300,8 @@ func (i Null) Dup() Item {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i Null) Bool() bool { return false }
|
func (i Null) TryBool() (bool, error) { return false, nil }
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
func (i Null) TryBytes() ([]byte, error) {
|
func (i Null) TryBytes() ([]byte, error) {
|
||||||
|
@ -346,9 +350,9 @@ func (i *BigInteger) Bytes() []byte {
|
||||||
return bigint.ToBytes(i.value)
|
return bigint.ToBytes(i.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *BigInteger) Bool() bool {
|
func (i *BigInteger) TryBool() (bool, error) {
|
||||||
return i.value.Sign() != 0
|
return i.value.Sign() != 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
|
@ -431,8 +435,8 @@ func (i *Bool) Dup() Item {
|
||||||
return &Bool{i.value}
|
return &Bool{i.value}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *Bool) Bool() bool { return i.value }
|
func (i *Bool) TryBool() (bool, error) { return i.value, nil }
|
||||||
|
|
||||||
// Bytes converts Bool to bytes.
|
// Bytes converts Bool to bytes.
|
||||||
func (i *Bool) Bytes() []byte {
|
func (i *Bool) Bytes() []byte {
|
||||||
|
@ -500,17 +504,17 @@ func (i *ByteArray) String() string {
|
||||||
return "ByteString"
|
return "ByteString"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *ByteArray) Bool() bool {
|
func (i *ByteArray) TryBool() (bool, error) {
|
||||||
if len(i.value) > MaxBigIntegerSizeBits/8 {
|
if len(i.value) > MaxBigIntegerSizeBits/8 {
|
||||||
return true
|
return false, errors.New("too big byte string")
|
||||||
}
|
}
|
||||||
for _, b := range i.value {
|
for _, b := range i.value {
|
||||||
if b != 0 {
|
if b != 0 {
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
|
@ -601,8 +605,8 @@ func (i *Array) String() string {
|
||||||
return "Array"
|
return "Array"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *Array) Bool() bool { return true }
|
func (i *Array) TryBool() (bool, error) { return true, nil }
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
func (i *Array) TryBytes() ([]byte, error) {
|
func (i *Array) TryBytes() ([]byte, error) {
|
||||||
|
@ -638,7 +642,7 @@ func (i *Array) Convert(typ Type) (Item, error) {
|
||||||
copy(arr, i.value)
|
copy(arr, i.value)
|
||||||
return NewStruct(arr), nil
|
return NewStruct(arr), nil
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(i.Bool()), nil
|
return NewBool(true), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidConversion
|
return nil, errInvalidConversion
|
||||||
}
|
}
|
||||||
|
@ -691,8 +695,8 @@ func (i *Map) Len() int {
|
||||||
return len(i.value)
|
return len(i.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *Map) Bool() bool { return true }
|
func (i *Map) TryBool() (bool, error) { return true, nil }
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
func (i *Map) TryBytes() ([]byte, error) {
|
func (i *Map) TryBytes() ([]byte, error) {
|
||||||
|
@ -743,7 +747,7 @@ func (i *Map) Convert(typ Type) (Item, error) {
|
||||||
case MapT:
|
case MapT:
|
||||||
return i, nil
|
return i, nil
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(i.Bool()), nil
|
return NewBool(true), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidConversion
|
return nil, errInvalidConversion
|
||||||
}
|
}
|
||||||
|
@ -807,8 +811,8 @@ func (i *Interop) Dup() Item {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *Interop) Bool() bool { return true }
|
func (i *Interop) TryBool() (bool, error) { return true, nil }
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
func (i *Interop) TryBytes() ([]byte, error) {
|
func (i *Interop) TryBytes() ([]byte, error) {
|
||||||
|
@ -840,7 +844,7 @@ func (i *Interop) Convert(typ Type) (Item, error) {
|
||||||
case InteropT:
|
case InteropT:
|
||||||
return i, nil
|
return i, nil
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(i.Bool()), nil
|
return NewBool(true), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidConversion
|
return nil, errInvalidConversion
|
||||||
}
|
}
|
||||||
|
@ -886,9 +890,9 @@ func (p *Pointer) Dup() Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (p *Pointer) Bool() bool {
|
func (p *Pointer) TryBool() (bool, error) {
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
|
@ -921,7 +925,7 @@ func (p *Pointer) Convert(typ Type) (Item, error) {
|
||||||
case PointerT:
|
case PointerT:
|
||||||
return p, nil
|
return p, nil
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(p.Bool()), nil
|
return NewBool(true), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidConversion
|
return nil, errInvalidConversion
|
||||||
}
|
}
|
||||||
|
@ -959,9 +963,9 @@ func (i *Buffer) String() string {
|
||||||
return "Buffer"
|
return "Buffer"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool implements Item interface.
|
// TryBool implements Item interface.
|
||||||
func (i *Buffer) Bool() bool {
|
func (i *Buffer) TryBool() (bool, error) {
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryBytes implements Item interface.
|
// TryBytes implements Item interface.
|
||||||
|
@ -998,7 +1002,7 @@ func (i *Buffer) Type() Type { return BufferT }
|
||||||
func (i *Buffer) Convert(typ Type) (Item, error) {
|
func (i *Buffer) Convert(typ Type) (Item, error) {
|
||||||
switch typ {
|
switch typ {
|
||||||
case BooleanT:
|
case BooleanT:
|
||||||
return NewBool(i.Bool()), nil
|
return NewBool(true), nil
|
||||||
case BufferT:
|
case BufferT:
|
||||||
return i, nil
|
return i, nil
|
||||||
case ByteArrayT:
|
case ByteArrayT:
|
||||||
|
|
2
pkg/vm/testdata/neo-vm
vendored
2
pkg/vm/testdata/neo-vm
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 359e8631ee2ddfefe8261afcec1a5bab9d9bddf9
|
Subproject commit 377464ed475a3de108e1bf9c834bd2279b72624e
|
Loading…
Reference in a new issue