]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/base32: handle surplus padding consistently
authorGustav Westling <zegl@westling.xyz>
Wed, 9 May 2018 21:02:14 +0000 (21:02 +0000)
committerIan Lance Taylor <iant@golang.org>
Wed, 9 May 2018 22:09:56 +0000 (22:09 +0000)
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

Change-Id: I07c36c35e6c83e795c3991bfe45647a35aa58aa4
GitHub-Last-Rev: 818dfda90b0edf9fc415da4579c5810268c1cdba
GitHub-Pull-Request: golang/go#25319
Reviewed-on: https://go-review.googlesource.com/112516
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/encoding/base32/base32.go
src/encoding/base32/base32_test.go

index e72ba74983e235f1a3ccb9263ed18e82ac721056..f3430654e1b486515565288ed5241d5bb41657fd 100644 (file)
@@ -409,9 +409,14 @@ func readEncodedData(r io.Reader, buf []byte, min int) (n int, err error) {
                nn, err = r.Read(buf[n:])
                n += nn
        }
+       // data was read, less than min bytes could be read
        if n < min && n > 0 && err == io.EOF {
                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
 }
 
index 56b229d15a6eee1bd45d43a4c440f79544e5235c..094ac288d64174d1185ed3620ff51e8ba8974eae 100644 (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) {
        type test struct {
                in      int