Commit 48c0cef6 authored by Cuong Manh Le's avatar Cuong Manh Le Committed by Brad Fitzpatrick

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 <cuong.manhle.vn@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 7de15e36
......@@ -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)
......
......@@ -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))
......
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