From 31aa66a4a481170c9abfdab7cc698a6e12824f2e Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 18 Nov 2020 14:13:09 +0300 Subject: [PATCH] core: check the length of NotValidBefore attr while decoding DecodeBinary throws panic otherwise. --- pkg/core/transaction/attribute_test.go | 26 +++++++++++++++++------- pkg/core/transaction/not_valid_before.go | 8 ++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/pkg/core/transaction/attribute_test.go b/pkg/core/transaction/attribute_test.go index 6857dc08d..1474ebfca 100644 --- a/pkg/core/transaction/attribute_test.go +++ b/pkg/core/transaction/attribute_test.go @@ -31,13 +31,25 @@ func TestAttribute_EncodeBinary(t *testing.T) { testserdes.EncodeDecodeBinary(t, attr, new(Attribute)) }) t.Run("NotValidBefore", func(t *testing.T) { - attr := &Attribute{ - Type: NotValidBeforeT, - Value: &NotValidBefore{ - Height: 123, - }, - } - testserdes.EncodeDecodeBinary(t, attr, new(Attribute)) + t.Run("positive", func(t *testing.T) { + attr := &Attribute{ + Type: NotValidBeforeT, + Value: &NotValidBefore{ + Height: 123, + }, + } + testserdes.EncodeDecodeBinary(t, attr, new(Attribute)) + }) + t.Run("bad format: too long", func(t *testing.T) { + bw := io.NewBufBinWriter() + bw.WriteVarBytes([]byte{1, 2, 3, 4, 5}) + require.Error(t, testserdes.DecodeBinary(bw.Bytes(), new(NotValidBefore))) + }) + t.Run("bad format: too short", func(t *testing.T) { + bw := io.NewBufBinWriter() + bw.WriteVarBytes([]byte{1, 2, 3}) + require.Error(t, testserdes.DecodeBinary(bw.Bytes(), new(NotValidBefore))) + }) }) t.Run("Reserved", func(t *testing.T) { getReservedAttribute := func(t AttrType) *Attribute { diff --git a/pkg/core/transaction/not_valid_before.go b/pkg/core/transaction/not_valid_before.go index c1596a277..aa64b14c0 100644 --- a/pkg/core/transaction/not_valid_before.go +++ b/pkg/core/transaction/not_valid_before.go @@ -2,6 +2,7 @@ package transaction import ( "encoding/binary" + "fmt" "github.com/nspcc-dev/neo-go/pkg/io" ) @@ -14,6 +15,13 @@ type NotValidBefore struct { // DecodeBinary implements io.Serializable interface. func (n *NotValidBefore) DecodeBinary(br *io.BinReader) { bytes := br.ReadVarBytes(4) + if br.Err != nil { + return + } + if len(bytes) != 4 { + br.Err = fmt.Errorf("expected 4 bytes, got %d", len(bytes)) + return + } n.Height = binary.LittleEndian.Uint32(bytes) }