Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions abci/strategies/codec/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package codec
import (
"bytes"
"compress/zlib"
"fmt"
"io"

cometabci "github.com/cometbft/cometbft/abci/types"
Expand Down Expand Up @@ -54,7 +55,13 @@ func (codec *DefaultVoteExtensionCodec) Encode(ve vetypes.OracleVoteExtension) (

func (codec *DefaultVoteExtensionCodec) Decode(bz []byte) (vetypes.OracleVoteExtension, error) {
var ve vetypes.OracleVoteExtension
return ve, ve.Unmarshal(bz)
if err := ve.Unmarshal(bz); err != nil {
return ve, err
}
if len(bz) != ve.Size() {
return ve, fmt.Errorf("non-canonical OracleVoteExtension encoding: got %d bytes, expected %d", len(bz), ve.Size())
}
return ve, nil
}

type Compressor interface {
Expand Down Expand Up @@ -95,14 +102,25 @@ func (c *ZLibCompressor) Decompress(bz []byte) ([]byte, error) {
if len(bz) == 0 {
return nil, nil
}
r, err := zlib.NewReader(bytes.NewReader(bz))
br := bytes.NewReader(bz)
r, err := zlib.NewReader(br)
if err != nil {
return nil, err
}
r.Close()

// read bytes and return
return io.ReadAll(r)
decompressed, err := io.ReadAll(r)
if err != nil {
r.Close()
return nil, err
}
if err := r.Close(); err != nil {
return nil, err
}
if br.Len() != 0 {
return nil, fmt.Errorf("zlib stream contains %d trailing bytes", br.Len())
}

return decompressed, nil
}

// ZStdCompressor is a Compressor that uses zstd to compress / decompress byte arrays, this object is thread-safe.
Expand Down
54 changes: 54 additions & 0 deletions abci/strategies/codec/codec_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package codec_test

import (
"encoding/binary"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -38,6 +39,24 @@
_, err := codec.Decode([]byte{})
require.Nil(t, err)
})

t.Run("test decoding vote extension rejects unknown protobuf field padding", func(t *testing.T) {
ve := vetypes.OracleVoteExtension{
Prices: map[uint64][]byte{
1: []byte("123"),
},
}

codec := compression.NewDefaultVoteExtensionCodec()
bz, err := codec.Encode(ve)
require.NoError(t, err)

paddedBz := appendUnknownFieldPadding(bz, 64*1024)
require.Greater(t, len(paddedBz), len(bz))

_, err = codec.Decode(paddedBz)
require.Error(t, err)
})
}

func TestCompressionVoteExtensionCodec(t *testing.T) {
Expand Down Expand Up @@ -80,6 +99,41 @@
_, err := codec.Decode([]byte{})
require.Nil(t, err)
})

t.Run("test decoding compressed vote extension rejects trailing padding", func(t *testing.T) {
ve := vetypes.OracleVoteExtension{
Prices: map[uint64][]byte{
1: []byte("123"),
},
}

codec := compression.NewCompressionVoteExtensionCodec(
compression.NewDefaultVoteExtensionCodec(),
compression.NewZLibCompressor(),
)
bz, err := codec.Encode(ve)
require.NoError(t, err)

paddedBz := append(bz, make([]byte, 64*1024)...)

Check failure on line 117 in abci/strategies/codec/codec_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

appendAssign: append result not assigned to the same slice (gocritic)
require.Greater(t, len(paddedBz), len(bz))

_, err = codec.Decode(paddedBz)
require.Error(t, err)
})
}

func appendUnknownFieldPadding(bz []byte, paddingSize int) []byte {
const field7LengthDelimited = byte(7<<3 | 2)

var lengthBuf [binary.MaxVarintLen64]byte
n := binary.PutUvarint(lengthBuf[:], uint64(paddingSize))

Check failure on line 129 in abci/strategies/codec/codec_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

G115: integer overflow conversion int -> uint64 (gosec)

padded := make([]byte, 0, len(bz)+1+n+paddingSize)
padded = append(padded, bz...)
padded = append(padded, field7LengthDelimited)
padded = append(padded, lengthBuf[:n]...)
padded = append(padded, make([]byte, paddingSize)...)
return padded
}

func TestDefaultExtendedCommitCodec(t *testing.T) {
Expand Down
Loading