Skip to content

Commit

Permalink
p2p/enr: fix decoding of incomplete lists (#22484)
Browse files Browse the repository at this point in the history
Given a list of less than two elements DecodeRLP returned rlp.EOL,
leading to issues in outer decoders.
  • Loading branch information
fjl authored Mar 11, 2021
1 parent 22082f9 commit aae7660
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
7 changes: 7 additions & 0 deletions p2p/enr/enr.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var (
errNotSorted = errors.New("record key/value pairs are not sorted by key")
errDuplicateKey = errors.New("record contains duplicate key")
errIncompletePair = errors.New("record contains incomplete k/v pair")
errIncompleteList = errors.New("record contains less than two list elements")
errTooBig = fmt.Errorf("record bigger than %d bytes", SizeLimit)
errEncodeUnsigned = errors.New("can't encode unsigned record")
errNotFound = errors.New("no such key in record")
Expand Down Expand Up @@ -209,9 +210,15 @@ func decodeRecord(s *rlp.Stream) (dec Record, raw []byte, err error) {
return dec, raw, err
}
if err = s.Decode(&dec.signature); err != nil {
if err == rlp.EOL {
err = errIncompleteList
}
return dec, raw, err
}
if err = s.Decode(&dec.seq); err != nil {
if err == rlp.EOL {
err = errIncompleteList
}
return dec, raw, err
}
// The rest of the record contains sorted k/v pairs.
Expand Down
23 changes: 23 additions & 0 deletions p2p/enr/enr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,29 @@ func TestRecordTooBig(t *testing.T) {
require.NoError(t, signTest([]byte{5}, &r))
}

// This checks that incomplete RLP inputs are handled correctly.
func TestDecodeIncomplete(t *testing.T) {
type decTest struct {
input []byte
err error
}
tests := []decTest{
{[]byte{0xC0}, errIncompleteList},
{[]byte{0xC1, 0x1}, errIncompleteList},
{[]byte{0xC2, 0x1, 0x2}, nil},
{[]byte{0xC3, 0x1, 0x2, 0x3}, errIncompletePair},
{[]byte{0xC4, 0x1, 0x2, 0x3, 0x4}, nil},
{[]byte{0xC5, 0x1, 0x2, 0x3, 0x4, 0x5}, errIncompletePair},
}
for _, test := range tests {
var r Record
err := rlp.DecodeBytes(test.input, &r)
if err != test.err {
t.Errorf("wrong error for %X: %v", test.input, err)
}
}
}

// TestSignEncodeAndDecodeRandom tests encoding/decoding of records containing random key/value pairs.
func TestSignEncodeAndDecodeRandom(t *testing.T) {
var r Record
Expand Down

0 comments on commit aae7660

Please sign in to comment.