Prechádzať zdrojové kódy

Add unit-test coverage for marshaling (#1205)

* Add unit-test coverage for marshalling

* Add test to see if Unmarshal will panic on a > 1000 payload

* Error instead of truncate on payloads over 1000 bytes

* Clarify intents and tests for vaa.Unmarshal
Jonathan Claudius 3 rokov pred
rodič
commit
0c22d6c3d6
2 zmenil súbory, kde vykonal 49 pridanie a 2 odobranie
  1. 5 0
      node/pkg/vaa/structs.go
  2. 44 2
      node/pkg/vaa/structs_test.go

+ 5 - 0
node/pkg/vaa/structs.go

@@ -243,6 +243,10 @@ const (
 )
 
 // Unmarshal deserializes the binary representation of a VAA
+//
+// WARNING: Unmarshall will truncate payloads at 1000 bytes, this is done mainly to avoid denial of service
+//   - If you need to access the full payload, consider parsing VAA from Bytes instead of Unmarshal
+//
 func Unmarshal(data []byte) (*VAA, error) {
 	if len(data) < minVAALength {
 		return nil, fmt.Errorf("VAA is too short")
@@ -316,6 +320,7 @@ func Unmarshal(data []byte) (*VAA, error) {
 	if err != nil || n == 0 {
 		return nil, fmt.Errorf("failed to read payload [%d]: %w", n, err)
 	}
+
 	v.Payload = payload[:n]
 
 	return v, nil

+ 44 - 2
node/pkg/vaa/structs_test.go

@@ -166,7 +166,7 @@ func getVaa() VAA {
 	return VAA{
 		Version:          uint8(1),
 		GuardianSetIndex: uint32(1),
-		Signatures:       nil,
+		Signatures:       []*Signature{},
 		Timestamp:        time.Unix(0, 0),
 		Nonce:            uint32(1),
 		Sequence:         uint64(1),
@@ -182,7 +182,7 @@ func TestAddSignature(t *testing.T) {
 
 	// Generate a random private key to sign with
 	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	assert.Nil(t, vaa.Signatures)
+	assert.Equal(t, []*Signature{}, vaa.Signatures)
 
 	// Add a signature and make sure it's added
 	vaa.AddSignature(key, 0)
@@ -219,6 +219,48 @@ func TestHexDigest(t *testing.T) {
 	assert.Equal(t, vaa.HexDigest(), expected)
 }
 
+func TestMarshal(t *testing.T) {
+	expectedBytes := []byte{0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}
+	vaa := getVaa()
+	marshalBytes, err := vaa.Marshal()
+	assert.Nil(t, err)
+	assert.Equal(t, expectedBytes, marshalBytes)
+}
+
+func TestUnmarshal(t *testing.T) {
+	vaaBytes := []byte{0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}
+	vaa1 := getVaa()
+	vaa2, err := Unmarshal(vaaBytes)
+	assert.Nil(t, err)
+	assert.Equal(t, &vaa1, vaa2)
+}
+
+func TestUnmarshalTooBig(t *testing.T) {
+	vaa := getVaa()
+
+	// Overwrite an oversized payload for the VAA that we cannot unmarshal
+	var payload []byte
+	for i := 0; i < 2000; i++ {
+		payload = append(payload, 'a')
+	}
+	vaa.Payload = payload
+
+	// Let's marshal the VAA to bytes to unmarshaled
+	marshalBytes, err := vaa.Marshal()
+	assert.Nil(t, err)
+
+	// Let's now unmarshal the oversized VAA and cause it to panic
+	vaa2, err2 := Unmarshal(marshalBytes)
+	assert.Nil(t, err2)
+
+	// Marshal the VAA
+	marshalBytes2, err3 := vaa2.Marshal()
+	assert.Nil(t, err3)
+
+	// Verify that it's truncated at to 1057 (57 byte header + 1000 byte payload)
+	assert.Equal(t, marshalBytes[:1057], marshalBytes2)
+}
+
 func TestVerifySignatures(t *testing.T) {
 	// Generate some random private keys to sign with
 	privKey1, _ := ecdsa.GenerateKey(crypto.S256(), rand.Reader)