stackitem: serialize/deserialize pointers, fix #2815
They of course can't be serialized, but in protected mode we still need to handle them somehow.
This commit is contained in:
parent
286f40b828
commit
9ba18b5dfa
2 changed files with 31 additions and 0 deletions
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MaxDeserialized is the maximum number one deserialized item can contain
|
// MaxDeserialized is the maximum number one deserialized item can contain
|
||||||
|
@ -168,6 +169,13 @@ func (w *SerializationContext) serialize(item Item) error {
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("%w: Interop", ErrUnserializable)
|
return fmt.Errorf("%w: Interop", ErrUnserializable)
|
||||||
}
|
}
|
||||||
|
case *Pointer:
|
||||||
|
if w.allowInvalid {
|
||||||
|
w.data = append(w.data, byte(PointerT))
|
||||||
|
w.appendVarUint(uint64(t.pos))
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("%w: Pointer", ErrUnserializable)
|
||||||
|
}
|
||||||
case *Array:
|
case *Array:
|
||||||
w.data = append(w.data, byte(ArrayT))
|
w.data = append(w.data, byte(ArrayT))
|
||||||
if err := w.writeArray(item, t.value, start); err != nil {
|
if err := w.writeArray(item, t.value, start); err != nil {
|
||||||
|
@ -311,6 +319,12 @@ func (r *deserContext) decodeBinary() Item {
|
||||||
return NewInterop(nil)
|
return NewInterop(nil)
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
case PointerT:
|
||||||
|
if r.allowInvalid {
|
||||||
|
pos := int(r.ReadVarUint())
|
||||||
|
return NewPointerWithHash(pos, nil, util.Uint160{})
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
default:
|
default:
|
||||||
if t == InvalidT && r.allowInvalid {
|
if t == InvalidT && r.allowInvalid {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -76,6 +76,7 @@ func TestSerialize(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("invalid", func(t *testing.T) {
|
t.Run("invalid", func(t *testing.T) {
|
||||||
testSerialize(t, ErrUnserializable, NewInterop(42))
|
testSerialize(t, ErrUnserializable, NewInterop(42))
|
||||||
|
testSerialize(t, ErrUnserializable, NewPointer(42, []byte{}))
|
||||||
testSerialize(t, ErrUnserializable, nil)
|
testSerialize(t, ErrUnserializable, nil)
|
||||||
|
|
||||||
t.Run("protected interop", func(t *testing.T) {
|
t.Run("protected interop", func(t *testing.T) {
|
||||||
|
@ -93,6 +94,22 @@ func TestSerialize(t *testing.T) {
|
||||||
require.NoError(t, r.Err)
|
require.NoError(t, r.Err)
|
||||||
require.IsType(t, (*Interop)(nil), item)
|
require.IsType(t, (*Interop)(nil), item)
|
||||||
})
|
})
|
||||||
|
t.Run("protected pointer", func(t *testing.T) {
|
||||||
|
w := io.NewBufBinWriter()
|
||||||
|
EncodeBinaryProtected(NewPointer(42, []byte{}), w.BinWriter)
|
||||||
|
require.NoError(t, w.Err)
|
||||||
|
|
||||||
|
data := w.Bytes()
|
||||||
|
r := io.NewBinReaderFromBuf(data)
|
||||||
|
DecodeBinary(r)
|
||||||
|
require.Error(t, r.Err)
|
||||||
|
|
||||||
|
r = io.NewBinReaderFromBuf(data)
|
||||||
|
item := DecodeBinaryProtected(r)
|
||||||
|
require.NoError(t, r.Err)
|
||||||
|
require.IsType(t, (*Pointer)(nil), item)
|
||||||
|
require.Equal(t, 42, item.Value())
|
||||||
|
})
|
||||||
t.Run("protected nil", func(t *testing.T) {
|
t.Run("protected nil", func(t *testing.T) {
|
||||||
w := io.NewBufBinWriter()
|
w := io.NewBufBinWriter()
|
||||||
EncodeBinaryProtected(nil, w.BinWriter)
|
EncodeBinaryProtected(nil, w.BinWriter)
|
||||||
|
|
Loading…
Reference in a new issue