From ed90fbc747b384a355ded46ff5c9164ca69b6590 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick <bradfitz@golang.org> Date: Mon, 30 Apr 2012 17:14:41 +1000 Subject: [PATCH] encoding/base64: don't ignore underlying souce read error in decode Fixes #3577 R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/6137054 --- src/pkg/encoding/base64/base64.go | 2 +- src/pkg/encoding/base64/base64_test.go | 49 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/pkg/encoding/base64/base64.go b/src/pkg/encoding/base64/base64.go index f8a51a4e75..0b842f0661 100644 --- a/src/pkg/encoding/base64/base64.go +++ b/src/pkg/encoding/base64/base64.go @@ -318,7 +318,7 @@ func (d *decoder) Read(p []byte) (n int, err error) { } nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf) d.nbuf += nn - if d.nbuf < 4 { + if d.err != nil || d.nbuf < 4 { return 0, d.err } diff --git a/src/pkg/encoding/base64/base64_test.go b/src/pkg/encoding/base64/base64_test.go index 9c35372598..f9b863c364 100644 --- a/src/pkg/encoding/base64/base64_test.go +++ b/src/pkg/encoding/base64/base64_test.go @@ -6,9 +6,11 @@ package base64 import ( "bytes" + "errors" "io" "io/ioutil" "testing" + "time" ) type testpair struct { @@ -226,3 +228,50 @@ func TestNewLineCharacters(t *testing.T) { } } } + +type nextRead struct { + n int // bytes to return + err error // error to return +} + +// faultInjectReader returns data from source, rate-limited +// and with the errors as written to nextc. +type faultInjectReader struct { + source string + nextc <-chan nextRead +} + +func (r *faultInjectReader) Read(p []byte) (int, error) { + nr := <-r.nextc + if len(p) > nr.n { + p = p[:nr.n] + } + n := copy(p, r.source) + r.source = r.source[n:] + return n, nr.err +} + +// tests that we don't ignore errors from our underlying reader +func TestDecoderIssue3577(t *testing.T) { + next := make(chan nextRead, 10) + wantErr := errors.New("my error") + next <- nextRead{5, nil} + next <- nextRead{10, wantErr} + d := NewDecoder(StdEncoding, &faultInjectReader{ + source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig... + nextc: next, + }) + errc := make(chan error) + go func() { + _, err := ioutil.ReadAll(d) + errc <- err + }() + select { + case err := <-errc: + if err != wantErr { + t.Errorf("got error %v; want %v", err, wantErr) + } + case <-time.After(5 * time.Second): + t.Errorf("timeout; Decoder blocked without returning an error") + } +} -- 2.30.9