Skip to content

Commit 018854d

Browse files
committed
[release-branch.go1.1] bufio: check buffer availability before reading in ReadFrom
This change was applied by hand, as bufio has seen some refactoring since 1.1 was branched. The only difference between this and the original patch is the offset of the change, and s/flush/Flush/. ««« CL 11801043 / 3ffbc06b4874 bufio: check buffer availability before reading in ReadFrom Fixes issue 5947 . R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/11801043 »»» Update #5928 R=golang-dev, r CC=golang-dev https://golang.org/cl/12002043
1 parent 2041d55 commit 018854d

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

src/pkg/bufio/bufio.go

+11-6
Original file line numberDiff line numberDiff line change
@@ -585,23 +585,28 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
585585
}
586586
var m int
587587
for {
588+
if b.Available() == 0 {
589+
if err1 := b.Flush(); err1 != nil {
590+
return n, err1
591+
}
592+
}
588593
m, err = r.Read(b.buf[b.n:])
589594
if m == 0 {
590595
break
591596
}
592597
b.n += m
593598
n += int64(m)
594-
if b.Available() == 0 {
595-
if err1 := b.Flush(); err1 != nil {
596-
return n, err1
597-
}
598-
}
599599
if err != nil {
600600
break
601601
}
602602
}
603603
if err == io.EOF {
604-
err = nil
604+
// If we filled the buffer exactly, flush pre-emptively.
605+
if b.Available() == 0 {
606+
err = b.Flush()
607+
} else {
608+
err = nil
609+
}
605610
}
606611
return n, err
607612
}

src/pkg/bufio/bufio_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,10 @@ func TestWriterReadFrom(t *testing.T) {
847847
t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input))
848848
continue
849849
}
850+
if err := w.Flush(); err != nil {
851+
t.Errorf("Flush returned %v", err)
852+
continue
853+
}
850854
if got, want := b.String(), string(input); got != want {
851855
t.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n", wi, ri, got, want)
852856
}
@@ -1003,6 +1007,24 @@ func TestReaderClearError(t *testing.T) {
10031007
}
10041008
}
10051009

1010+
// Test for golang.org/issue/5947
1011+
func TestWriterReadFromWhileFull(t *testing.T) {
1012+
buf := new(bytes.Buffer)
1013+
w := NewWriterSize(buf, 10)
1014+
1015+
// Fill buffer exactly.
1016+
n, err := w.Write([]byte("0123456789"))
1017+
if n != 10 || err != nil {
1018+
t.Fatalf("Write returned (%v, %v), want (10, nil)", n, err)
1019+
}
1020+
1021+
// Use ReadFrom to read in some data.
1022+
n2, err := w.ReadFrom(strings.NewReader("abcdef"))
1023+
if n2 != 6 || err != nil {
1024+
t.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n, err)
1025+
}
1026+
}
1027+
10061028
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
10071029
type onlyReader struct {
10081030
r io.Reader

0 commit comments

Comments
 (0)