rlp: handle case of normal EOF in Stream.readFull (#22336)
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.
This commit is contained in:
		
							parent
							
								
									52e5c38aa5
								
							
						
					
					
						commit
						9ec32a9e7b
					
				| @ -952,7 +952,13 @@ func (s *Stream) readFull(buf []byte) (err error) { | |||||||
| 		n += nn | 		n += nn | ||||||
| 	} | 	} | ||||||
| 	if err == io.EOF { | 	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 | 	return err | ||||||
| } | } | ||||||
|  | |||||||
| @ -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
 | // plainReader reads from a byte slice but does not
 | ||||||
| // implement ReadByte. It is also not recognized by the
 | // implement ReadByte. It is also not recognized by the
 | ||||||
| // size validation. This is useful to test how the decoder
 | // size validation. This is useful to test how the decoder
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user