1
0
mirror of https://github.com/golang/go synced 2024-11-18 02:14:45 -07:00

encoding/base32: handle surplus padding consistently

This changes decoder.Read to always return io.ErrUnexpectedEOF if the input
contains surplus padding or unexpected content. Previously the error could
be io.EOF or io.ErrUnexpectedEOF depending on how the input was chunked.

Fixes #25296
This commit is contained in:
Gustav Westling 2018-05-09 22:52:07 +02:00
parent 814c749c8f
commit 818dfda90b
2 changed files with 85 additions and 0 deletions

View File

@ -409,9 +409,14 @@ func readEncodedData(r io.Reader, buf []byte, min int) (n int, err error) {
nn, err = r.Read(buf[n:]) nn, err = r.Read(buf[n:])
n += nn n += nn
} }
// data was read, less than min bytes could be read
if n < min && n > 0 && err == io.EOF { if n < min && n > 0 && err == io.EOF {
err = io.ErrUnexpectedEOF err = io.ErrUnexpectedEOF
} }
// no data was read, the buffer already contains some data
if min < 8 && n == 0 && err == io.EOF {
err = io.ErrUnexpectedEOF
}
return return
} }

View File

@ -530,6 +530,86 @@ func TestDecodeWithWrongPadding(t *testing.T) {
} }
} }
func TestBufferedDecodingSameError(t *testing.T) {
testcases := []struct {
prefix string
chunkCombinations [][]string
expected error
}{
// NBSWY3DPO5XXE3DE == helloworld
// Test with "ZZ" as extra input
{"helloworld", [][]string{
[]string{"NBSW", "Y3DP", "O5XX", "E3DE", "ZZ"},
[]string{"NBSWY3DPO5XXE3DE", "ZZ"},
[]string{"NBSWY3DPO5XXE3DEZZ"},
[]string{"NBS", "WY3", "DPO", "5XX", "E3D", "EZZ"},
[]string{"NBSWY3DPO5XXE3", "DEZZ"},
}, io.ErrUnexpectedEOF},
// Test with "ZZY" as extra input
{"helloworld", [][]string{
[]string{"NBSW", "Y3DP", "O5XX", "E3DE", "ZZY"},
[]string{"NBSWY3DPO5XXE3DE", "ZZY"},
[]string{"NBSWY3DPO5XXE3DEZZY"},
[]string{"NBS", "WY3", "DPO", "5XX", "E3D", "EZZY"},
[]string{"NBSWY3DPO5XXE3", "DEZZY"},
}, io.ErrUnexpectedEOF},
// Normal case, this is valid input
{"helloworld", [][]string{
[]string{"NBSW", "Y3DP", "O5XX", "E3DE"},
[]string{"NBSWY3DPO5XXE3DE"},
[]string{"NBS", "WY3", "DPO", "5XX", "E3D", "E"},
[]string{"NBSWY3DPO5XXE3", "DE"},
}, nil},
// MZXW6YTB = fooba
{"fooba", [][]string{
[]string{"MZXW6YTBZZ"},
[]string{"MZXW6YTBZ", "Z"},
[]string{"MZXW6YTB", "ZZ"},
[]string{"MZXW6YT", "BZZ"},
[]string{"MZXW6Y", "TBZZ"},
[]string{"MZXW6Y", "TB", "ZZ"},
[]string{"MZXW6", "YTBZZ"},
[]string{"MZXW6", "YTB", "ZZ"},
[]string{"MZXW6", "YT", "BZZ"},
}, io.ErrUnexpectedEOF},
// Normal case, this is valid input
{"fooba", [][]string{
[]string{"MZXW6YTB"},
[]string{"MZXW6YT", "B"},
[]string{"MZXW6Y", "TB"},
[]string{"MZXW6", "YTB"},
[]string{"MZXW6", "YT", "B"},
[]string{"MZXW", "6YTB"},
[]string{"MZXW", "6Y", "TB"},
}, nil},
}
for _, testcase := range testcases {
for _, chunks := range testcase.chunkCombinations {
pr, pw := io.Pipe()
// Write the encoded chunks into the pipe
go func() {
for _, chunk := range chunks {
pw.Write([]byte(chunk))
}
pw.Close()
}()
decoder := NewDecoder(StdEncoding, pr)
_, err := ioutil.ReadAll(decoder)
if err != testcase.expected {
t.Errorf("Expected %v, got %v; case %s %+v", testcase.expected, err, testcase.prefix, chunks)
}
}
}
}
func TestEncodedDecodedLen(t *testing.T) { func TestEncodedDecodedLen(t *testing.T) {
type test struct { type test struct {
in int in int