From: Cuong Manh Le Date: Tue, 29 Oct 2019 06:27:00 +0000 (+0700) Subject: bufio: return the underlying error in ReadFrom if not nil X-Git-Tag: go1.14beta1~484 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=48c0cef6dc9e7c95edaffb261250f99732686466;p=gostls13.git bufio: return the underlying error in ReadFrom if not nil 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 Run-TryBot: Brad Fitzpatrick Reviewed-by: Brad Fitzpatrick Reviewed-by: Emmanuel Odeke Reviewed-by: Ian Lance Taylor TryBot-Result: Gobot Gobot --- diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go index d1d542a484..f0810be3a4 100644 --- a/src/bufio/bufio.go +++ b/src/bufio/bufio.go @@ -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) diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go index 3e085fd5d0..9a9f102f15 100644 --- a/src/bufio/bufio_test.go +++ b/src/bufio/bufio_test.go @@ -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))