Commit 018854d2 authored by Andrew Gerrand's avatar Andrew Gerrand

[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
parent 2041d55a
...@@ -585,23 +585,28 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) { ...@@ -585,23 +585,28 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
} }
var m int var m int
for { for {
if b.Available() == 0 {
if err1 := b.Flush(); err1 != nil {
return n, err1
}
}
m, err = r.Read(b.buf[b.n:]) m, err = r.Read(b.buf[b.n:])
if m == 0 { if m == 0 {
break break
} }
b.n += m b.n += m
n += int64(m) n += int64(m)
if b.Available() == 0 {
if err1 := b.Flush(); err1 != nil {
return n, err1
}
}
if err != nil { if err != nil {
break break
} }
} }
if err == io.EOF { 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 return n, err
} }
......
...@@ -847,6 +847,10 @@ func TestWriterReadFrom(t *testing.T) { ...@@ -847,6 +847,10 @@ func TestWriterReadFrom(t *testing.T) {
t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input)) t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input))
continue continue
} }
if err := w.Flush(); err != nil {
t.Errorf("Flush returned %v", err)
continue
}
if got, want := b.String(), string(input); got != want { if got, want := b.String(), string(input); got != want {
t.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n", wi, ri, got, want) t.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n", wi, ri, got, want)
} }
...@@ -1003,6 +1007,24 @@ func TestReaderClearError(t *testing.T) { ...@@ -1003,6 +1007,24 @@ func TestReaderClearError(t *testing.T) {
} }
} }
// 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)
}
}
// 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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment