src/pkg/bufio/bufio.go | 17 +++++++++++------ src/pkg/bufio/bufio_test.go | 22 ++++++++++++++++++++++ diff --git a/src/pkg/bufio/bufio.go b/src/pkg/bufio/bufio.go index df3501f2ca1776dfae856aa2bfa8c4e3002aa803..10e12d42be8440d63805984cfe35f408473b2a54 100644 --- a/src/pkg/bufio/bufio.go +++ b/src/pkg/bufio/bufio.go @@ -585,23 +585,28 @@ } } var m int for { + if b.Available() == 0 { + if err1 := b.Flush(); err1 != nil { + return n, err1 + } + } m, err = r.Read(b.buf[b.n:]) if m == 0 { break } b.n += m n += int64(m) - if b.Available() == 0 { - if err1 := b.Flush(); err1 != nil { - return n, err1 - } - } if err != nil { break } } if err == io.EOF { - err = nil + // If we filled the buffer exactly, flush pre-emptively. + if b.Available() == 0 { + err = b.Flush() + } else { + err = nil + } } return n, err } diff --git a/src/pkg/bufio/bufio_test.go b/src/pkg/bufio/bufio_test.go index 79ed0f178e036ccab1ffb7b2fe166a6138267ecc..9fcbfda68dc2c37592bfd921cfd882c4571cd4d1 100644 --- a/src/pkg/bufio/bufio_test.go +++ b/src/pkg/bufio/bufio_test.go @@ -847,6 +847,10 @@ if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) { t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input)) continue } + if err := w.Flush(); err != nil { + t.Errorf("Flush returned %v", err) + continue + } if got, want := b.String(), string(input); got != want { t.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n", wi, ri, got, want) } @@ -1000,6 +1004,24 @@ t.Fatalf("3rd Read with buffer = %v; want nil", err) } if r.nread != 2 { t.Errorf("num reads = %d; want 2", r.nread) + } +} + +// Test for golang.org/issue/5947 +func TestWriterReadFromWhileFull(t *testing.T) { + buf := new(bytes.Buffer) + w := NewWriterSize(buf, 10) + + // Fill buffer exactly. + n, err := w.Write([]byte("0123456789")) + if n != 10 || err != nil { + t.Fatalf("Write returned (%v, %v), want (10, nil)", n, err) + } + + // Use ReadFrom to read in some data. + n2, err := w.ReadFrom(strings.NewReader("abcdef")) + if n2 != 6 || err != nil { + t.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n, err) } }