aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/base32/base32.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/base32/base32.go')
-rw-r--r--src/encoding/base32/base32.go41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/encoding/base32/base32.go b/src/encoding/base32/base32.go
index c193e65e1b..788a06115a 100644
--- a/src/encoding/base32/base32.go
+++ b/src/encoding/base32/base32.go
@@ -343,18 +343,33 @@ type decoder struct {
outbuf [1024 / 8 * 5]byte
}
-func (d *decoder) Read(p []byte) (n int, err error) {
- if d.err != nil {
- return 0, d.err
+func readEncodedData(r io.Reader, buf []byte, min int) (n int, err error) {
+ for n < min && err == nil {
+ var nn int
+ nn, err = r.Read(buf[n:])
+ n += nn
+ }
+ if n < min && n > 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
}
+ return
+}
+func (d *decoder) Read(p []byte) (n int, err error) {
// Use leftover decoded output from last read.
if len(d.out) > 0 {
n = copy(p, d.out)
d.out = d.out[n:]
+ if len(d.out) == 0 {
+ return n, d.err
+ }
return n, nil
}
+ if d.err != nil {
+ return 0, d.err
+ }
+
// Read a chunk.
nn := len(p) / 5 * 8
if nn < 8 {
@@ -363,7 +378,8 @@ func (d *decoder) Read(p []byte) (n int, err error) {
if nn > len(d.buf) {
nn = len(d.buf)
}
- nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf)
+
+ nn, d.err = readEncodedData(d.r, d.buf[d.nbuf:nn], 8-d.nbuf)
d.nbuf += nn
if d.nbuf < 8 {
return 0, d.err
@@ -373,21 +389,30 @@ func (d *decoder) Read(p []byte) (n int, err error) {
nr := d.nbuf / 8 * 8
nw := d.nbuf / 8 * 5
if nw > len(p) {
- nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
+ nw, d.end, err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
d.out = d.outbuf[0:nw]
n = copy(p, d.out)
d.out = d.out[n:]
} else {
- n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
+ n, d.end, err = d.enc.decode(p, d.buf[0:nr])
}
d.nbuf -= nr
for i := 0; i < d.nbuf; i++ {
d.buf[i] = d.buf[i+nr]
}
- if d.err == nil {
+ if err != nil && (d.err == nil || d.err == io.EOF) {
d.err = err
}
+
+ if len(d.out) > 0 {
+ // We cannot return all the decoded bytes to the caller in this
+ // invocation of Read, so we return a nil error to ensure that Read
+ // will be called again. The error stored in d.err, if any, will be
+ // returned with the last set of decoded bytes.
+ return n, nil
+ }
+
return n, d.err
}
@@ -407,7 +432,7 @@ func (r *newlineFilteringReader) Read(p []byte) (int, error) {
offset++
}
}
- if offset > 0 {
+ if err != nil || offset > 0 {
return offset, err
}
// Previous buffer entirely whitespace, read again