209
218
// decode is like Decode but returns an additional 'end' value, which
210
219
// indicates if end-of-message padding was encountered and thus any
211
// additional data is an error.
220
// additional data is an error. This method assumes that src has been
221
// stripped of all supported whitespace ('\r' and '\n').
212
222
func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
214
224
for len(src) > 0 && !end {
215
225
// Decode quantum using the base64 alphabet
220
229
for j := 0; j < 4; {
221
230
if len(src) == 0 {
222
return n, false, CorruptInputError(len(osrc) - len(src) - j)
231
return n, false, CorruptInputError(olen - len(src) - j)
226
if in == '\r' || in == '\n' {
227
// Ignore this character.
230
235
if in == '=' && j >= 2 && len(src) < 4 {
231
// We've reached the end and there's
233
if len(src) == 0 && j == 2 {
236
// We've reached the end and there's padding
237
if len(src)+j < 4-1 {
234
238
// not enough padding
235
return n, false, CorruptInputError(len(osrc))
239
return n, false, CorruptInputError(olen)
237
241
if len(src) > 0 && src[0] != '=' {
238
242
// incorrect padding
239
return n, false, CorruptInputError(len(osrc) - len(src) - 1)
243
return n, false, CorruptInputError(olen - len(src) - 1)
245
248
dbuf[j] = enc.decodeMap[in]
246
249
if dbuf[j] == 0xFF {
247
return n, false, CorruptInputError(len(osrc) - len(src) - 1)
250
return n, false, CorruptInputError(olen - len(src) - 1)
274
277
// number of bytes successfully written and CorruptInputError.
275
278
// New line characters (\r and \n) are ignored.
276
279
func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
280
src = bytes.Map(removeNewlinesMapper, src)
277
281
n, _, err = enc.decode(dst, src)
281
285
// DecodeString returns the bytes represented by the base64 string s.
282
286
func (enc *Encoding) DecodeString(s string) ([]byte, error) {
287
s = strings.Map(removeNewlinesMapper, s)
283
288
dbuf := make([]byte, enc.DecodedLen(len(s)))
284
289
n, err := enc.Decode(dbuf, []byte(s))
285
290
return dbuf[:n], err
352
type newlineFilteringReader struct {
356
func (r *newlineFilteringReader) Read(p []byte) (int, error) {
357
n, err := r.wrapped.Read(p)
360
for i, b := range p[0:n] {
361
if b != '\r' && b != '\n' {
371
// Previous buffer entirely whitespace, read again
372
n, err = r.wrapped.Read(p)
347
377
// NewDecoder constructs a new base64 stream decoder.
348
378
func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
349
return &decoder{enc: enc, r: r}
379
return &decoder{enc: enc, r: &newlineFilteringReader{r}}
352
382
// DecodedLen returns the maximum length in bytes of the decoded data