mirror of https://github.com/golang/go.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 <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>
This commit is contained in:
parent
7de15e362b
commit
48c0cef6dc
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue