]> Cypherpunks.ru repositories - gostls13.git/commitdiff
bufio: return the underlying error in ReadFrom if not nil
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 29 Oct 2019 06:27:00 +0000 (13:27 +0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 31 Oct 2019 17:21:56 +0000 (17:21 +0000)
If a previous Write returned an error, any subsequent Write or ReadFrom
must return that error before any operations.

However, only Write behaved correctly and this change fixes that problem
by making sure that ReadFrom firstly checks for the underlying error.

Fixes #35194

Change-Id: I31356a9e8bd945bc0168b2e3be470f3ae69d4813
Reviewed-on: https://go-review.googlesource.com/c/go/+/204000
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

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

index d1d542a484664bfdd17cd2ee6188e6186336c032..f0810be3a44e9743542971386338a6176b8aa269 100644 (file)
@@ -706,6 +706,9 @@ func (b *Writer) WriteString(s string) (int, error) {
 // supports the ReadFrom method, and b has no buffered data yet,
 // this calls the underlying ReadFrom without buffering.
 func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
+       if b.err != nil {
+               return 0, b.err
+       }
        if b.Buffered() == 0 {
                if w, ok := b.wr.(io.ReaderFrom); ok {
                        n, err = w.ReadFrom(r)
index 3e085fd5d0cd58bd6d6cdd4d37230ed311efab5b..9a9f102f151e78ddf4aae24e6cd1c694ffc213f3 100644 (file)
@@ -1555,6 +1555,32 @@ func TestWriterReadFromMustSetUnderlyingError(t *testing.T) {
        }
 }
 
+type writeErrorOnlyWriter struct{}
+
+func (w writeErrorOnlyWriter) Write(p []byte) (n int, err error) {
+       return 0, errors.New("writeErrorOnlyWriter error")
+}
+
+// Ensure that previous Write errors are immediately returned
+// on any ReadFrom. See golang.org/issue/35194.
+func TestWriterReadFromMustReturnUnderlyingError(t *testing.T) {
+       var wr = NewWriter(writeErrorOnlyWriter{})
+       s := "test1"
+       wantBuffered := len(s)
+       if _, err := wr.WriteString(s); err != nil {
+               t.Fatalf("unexpected error: %v", err)
+       }
+       if err := wr.Flush(); err == nil {
+               t.Error("expected flush error, got nil")
+       }
+       if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
+               t.Fatal("expected error, got nil")
+       }
+       if buffered := wr.Buffered(); buffered != wantBuffered {
+               t.Fatalf("Buffered = %v; want %v", buffered, wantBuffered)
+       }
+}
+
 func BenchmarkReaderCopyOptimal(b *testing.B) {
        // Optimal case is where the underlying reader implements io.WriterTo
        srcBuf := bytes.NewBuffer(make([]byte, 8192))