1
0
mirror of https://github.com/golang/go synced 2024-11-20 06:04:52 -07:00

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
This commit is contained in:
Russ Cox 2012-12-10 17:25:31 -05:00
parent 9838774622
commit f0d9ccb8da
2 changed files with 31 additions and 0 deletions

View File

@ -64,6 +64,8 @@ func NewReader(rd io.Reader) *Reader {
return NewReaderSize(rd, defaultBufSize) return NewReaderSize(rd, defaultBufSize)
} }
var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
// fill reads a new chunk into the buffer. // fill reads a new chunk into the buffer.
func (b *Reader) fill() { func (b *Reader) fill() {
// Slide existing data to beginning. // Slide existing data to beginning.
@ -75,6 +77,9 @@ func (b *Reader) fill() {
// Read new data. // Read new data.
n, e := b.rd.Read(b.buf[b.w:]) n, e := b.rd.Read(b.buf[b.w:])
if n < 0 {
panic(errNegativeRead)
}
b.w += n b.w += n
if e != nil { if e != nil {
b.err = e b.err = e
@ -282,6 +287,9 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
// of the line. The returned buffer is only valid until the next call to // of the line. The returned buffer is only valid until the next call to
// ReadLine. ReadLine either returns a non-nil line or it returns an error, // ReadLine. ReadLine either returns a non-nil line or it returns an error,
// never both. // never both.
//
// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
// No indication or error is given if the input ends without a final line end.
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) { func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
line, err = b.ReadSlice('\n') line, err = b.ReadSlice('\n')
if err == ErrBufferFull { if err == ErrBufferFull {

View File

@ -939,6 +939,29 @@ func (w *writeCountingDiscard) Write(p []byte) (int, error) {
return len(p), nil return len(p), nil
} }
type negativeReader int
func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
func TestNegativeRead(t *testing.T) {
// should panic with a description pointing at the reader, not at itself.
// (should NOT panic with slice index error, for example.)
b := NewReader(new(negativeReader))
defer func() {
switch err := recover().(type) {
case nil:
t.Fatal("read did not panic")
case error:
if !strings.Contains(err.Error(), "reader returned negative count from Read") {
t.Fatal("wrong panic: %v", err)
}
default:
t.Fatalf("unexpected panic value: %T(%v)", err, err)
}
}()
b.Read(make([]byte, 100))
}
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have. // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
type onlyReader struct { type onlyReader struct {
r io.Reader r io.Reader