mirror of https://github.com/golang/go.git
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
This commit is contained in:
parent
fe2ce5285e
commit
ed90fbc747
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue