]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.1] bufio: check buffer availability before reading in ReadFrom
authorAndrew Gerrand <adg@golang.org>
Mon, 29 Jul 2013 08:00:58 +0000 (18:00 +1000)
committerAndrew Gerrand <adg@golang.org>
Mon, 29 Jul 2013 08:00:58 +0000 (18:00 +1000)
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

src/pkg/bufio/bufio.go
src/pkg/bufio/bufio_test.go

index df3501f2ca1776dfae856aa2bfa8c4e3002aa803..10e12d42be8440d63805984cfe35f408473b2a54 100644 (file)
@@ -585,23 +585,28 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
        }
        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
 }
index 79ed0f178e036ccab1ffb7b2fe166a6138267ecc..9fcbfda68dc2c37592bfd921cfd882c4571cd4d1 100644 (file)
@@ -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))
                                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)
                        }
@@ -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.
 type onlyReader struct {
        r io.Reader