]> Cypherpunks repositories - gostls13.git/commitdiff
base64: fix bug that decoder fails to detect corruption
authorRui Ueyama <ruiu@google.com>
Thu, 20 Mar 2014 05:00:34 +0000 (16:00 +1100)
committerNigel Tao <nigeltao@golang.org>
Thu, 20 Mar 2014 05:00:34 +0000 (16:00 +1100)
Encoding.Decode() failed to detect trailing garbages if input contains "==" followed by garbage smaller than 3 bytes (for example, it failed to detect "x" in "AA==x"). This patch fixes the bug and adds a few tests.

LGTM=nigeltao
R=golang-codereviews, bradfitz, nigeltao
CC=golang-codereviews
https://golang.org/cl/75340044

src/pkg/encoding/base64/base64.go
src/pkg/encoding/base64/base64_test.go

index 0b07e733a0dcfb272dadca815858e5daa995f3bd..a6efd44615753dd08128899c75af27cb367ceca0 100644 (file)
@@ -224,21 +224,33 @@ func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
                var dbuf [4]byte
                dlen := 4
 
-               for j := 0; j < 4; {
+               for j := range dbuf {
                        if len(src) == 0 {
                                return n, false, CorruptInputError(olen - len(src) - j)
                        }
                        in := src[0]
                        src = src[1:]
-                       if in == '=' && j >= 2 && len(src) < 4 {
+                       if in == '=' {
                                // We've reached the end and there's padding
-                               if len(src)+j < 4-1 {
-                                       // not enough padding
-                                       return n, false, CorruptInputError(olen)
-                               }
-                               if len(src) > 0 && src[0] != '=' {
+                               switch j {
+                               case 0, 1:
                                        // incorrect padding
                                        return n, false, CorruptInputError(olen - len(src) - 1)
+                               case 2:
+                                       // "==" is expected, the first "=" is already consumed.
+                                       if len(src) == 0 {
+                                               // not enough padding
+                                               return n, false, CorruptInputError(olen)
+                                       }
+                                       if src[0] != '=' {
+                                               // incorrect padding
+                                               return n, false, CorruptInputError(olen - len(src) - 1)
+                                       }
+                                       src = src[1:]
+                               }
+                               if len(src) > 0 {
+                                       // trailing garbage
+                                       return n, false, CorruptInputError(olen - len(src))
                                }
                                dlen, end = j, true
                                break
@@ -247,7 +259,6 @@ func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
                        if dbuf[j] == 0xFF {
                                return n, false, CorruptInputError(olen - len(src) - 1)
                        }
-                       j++
                }
 
                // Pack 4x 6-bit source blocks into 3 byte destination
index 6bcc724d9b5702fc4d42e67bd5df2d9a1cef5cb1..0285629029e69378a07dc42bfb08aa2a651b0308 100644 (file)
@@ -149,9 +149,13 @@ func TestDecodeCorrupt(t *testing.T) {
        }{
                {"", -1},
                {"!!!!", 0},
+               {"====", 0},
                {"x===", 1},
+               {"=AAA", 0},
+               {"A=AA", 1},
                {"AA=A", 2},
-               {"AAA=AAAA", 3},
+               {"AA==A", 4},
+               {"AAA=AAAA", 4},
                {"AAAAA", 4},
                {"AAAAAA", 4},
                {"A=", 1},