Skip to content

Commit

Permalink
rlp: handle case of normal EOF in Stream.readFull (#22336)
Browse files Browse the repository at this point in the history
io.Reader may return n > 0 and io.EOF at the end of the input stream.
readFull did not handle this correctly, looking only at the error. This fixes
it to check for n == len(buf) as well.
  • Loading branch information
oneeman committed Feb 18, 2021
1 parent 52e5c38 commit 9ec32a9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
8 changes: 7 additions & 1 deletion rlp/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,13 @@ func (s *Stream) readFull(buf []byte) (err error) {
n += nn
}
if err == io.EOF {
err = io.ErrUnexpectedEOF
if n < len(buf) {
err = io.ErrUnexpectedEOF
} else {
// Readers are allowed to give EOF even though the read succeeded.
// In such cases, we discard the EOF, like io.ReadFull() does.
err = nil
}
}
return err
}
Expand Down
20 changes: 20 additions & 0 deletions rlp/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,26 @@ func TestDecodeWithByteReader(t *testing.T) {
})
}

func testDecodeWithEncReader(t *testing.T, n int) {
s := strings.Repeat("0", n)
_, r, _ := EncodeToReader(s)
var decoded string
err := Decode(r, &decoded)
if err != nil {
t.Errorf("Unexpected decode error with n=%v: %v", n, err)
}
if decoded != s {
t.Errorf("Decode mismatch with n=%v", n)
}
}

// This is a regression test checking that decoding from encReader
// works for RLP values of size 8192 bytes or more.
func TestDecodeWithEncReader(t *testing.T) {
testDecodeWithEncReader(t, 8188) // length with header is 8191
testDecodeWithEncReader(t, 8189) // length with header is 8192
}

// plainReader reads from a byte slice but does not
// implement ReadByte. It is also not recognized by the
// size validation. This is useful to test how the decoder
Expand Down

0 comments on commit 9ec32a9

Please sign in to comment.