Skip to content

Commit f0d9ccb

Browse files
committed
bufio: minor fixes
* note end-of-line and EOF behavior for ReadLine * diagnose broken Readers Fixes #3825. Fixes #4276. R=golang-dev, dave CC=golang-dev https://golang.org/cl/6907060
1 parent 9838774 commit f0d9ccb

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/pkg/bufio/bufio.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ func NewReader(rd io.Reader) *Reader {
6464
return NewReaderSize(rd, defaultBufSize)
6565
}
6666

67+
var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
68+
6769
// fill reads a new chunk into the buffer.
6870
func (b *Reader) fill() {
6971
// Slide existing data to beginning.
@@ -75,6 +77,9 @@ func (b *Reader) fill() {
7577

7678
// Read new data.
7779
n, e := b.rd.Read(b.buf[b.w:])
80+
if n < 0 {
81+
panic(errNegativeRead)
82+
}
7883
b.w += n
7984
if e != nil {
8085
b.err = e
@@ -282,6 +287,9 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
282287
// of the line. The returned buffer is only valid until the next call to
283288
// ReadLine. ReadLine either returns a non-nil line or it returns an error,
284289
// never both.
290+
//
291+
// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
292+
// No indication or error is given if the input ends without a final line end.
285293
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
286294
line, err = b.ReadSlice('\n')
287295
if err == ErrBufferFull {

src/pkg/bufio/bufio_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,29 @@ func (w *writeCountingDiscard) Write(p []byte) (int, error) {
939939
return len(p), nil
940940
}
941941

942+
type negativeReader int
943+
944+
func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
945+
946+
func TestNegativeRead(t *testing.T) {
947+
// should panic with a description pointing at the reader, not at itself.
948+
// (should NOT panic with slice index error, for example.)
949+
b := NewReader(new(negativeReader))
950+
defer func() {
951+
switch err := recover().(type) {
952+
case nil:
953+
t.Fatal("read did not panic")
954+
case error:
955+
if !strings.Contains(err.Error(), "reader returned negative count from Read") {
956+
t.Fatal("wrong panic: %v", err)
957+
}
958+
default:
959+
t.Fatalf("unexpected panic value: %T(%v)", err, err)
960+
}
961+
}()
962+
b.Read(make([]byte, 100))
963+
}
964+
942965
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
943966
type onlyReader struct {
944967
r io.Reader

0 commit comments

Comments
 (0)