github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/encoding/base64/base64_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package base64 6 7 import ( 8 "bytes" 9 "errors" 10 "io" 11 "io/ioutil" 12 "strings" 13 "testing" 14 "time" 15 ) 16 17 type testpair struct { 18 decoded, encoded string 19 } 20 21 var pairs = []testpair{ 22 // RFC 3548 examples 23 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"}, 24 {"\x14\xfb\x9c\x03\xd9", "FPucA9k="}, 25 {"\x14\xfb\x9c\x03", "FPucAw=="}, 26 27 // RFC 4648 examples 28 {"", ""}, 29 {"f", "Zg=="}, 30 {"fo", "Zm8="}, 31 {"foo", "Zm9v"}, 32 {"foob", "Zm9vYg=="}, 33 {"fooba", "Zm9vYmE="}, 34 {"foobar", "Zm9vYmFy"}, 35 36 // Wikipedia examples 37 {"sure.", "c3VyZS4="}, 38 {"sure", "c3VyZQ=="}, 39 {"sur", "c3Vy"}, 40 {"su", "c3U="}, 41 {"leasure.", "bGVhc3VyZS4="}, 42 {"easure.", "ZWFzdXJlLg=="}, 43 {"asure.", "YXN1cmUu"}, 44 {"sure.", "c3VyZS4="}, 45 } 46 47 var bigtest = testpair{ 48 "Twas brillig, and the slithy toves", 49 "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", 50 } 51 52 func testEqual(t *testing.T, msg string, args ...interface{}) bool { 53 if args[len(args)-2] != args[len(args)-1] { 54 t.Errorf(msg, args...) 55 return false 56 } 57 return true 58 } 59 60 func TestEncode(t *testing.T) { 61 for _, p := range pairs { 62 got := StdEncoding.EncodeToString([]byte(p.decoded)) 63 testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded) 64 } 65 } 66 67 func TestEncoder(t *testing.T) { 68 for _, p := range pairs { 69 bb := &bytes.Buffer{} 70 encoder := NewEncoder(StdEncoding, bb) 71 encoder.Write([]byte(p.decoded)) 72 encoder.Close() 73 testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded) 74 } 75 } 76 77 func TestEncoderBuffering(t *testing.T) { 78 input := []byte(bigtest.decoded) 79 for bs := 1; bs <= 12; bs++ { 80 bb := &bytes.Buffer{} 81 encoder := NewEncoder(StdEncoding, bb) 82 for pos := 0; pos < len(input); pos += bs { 83 end := pos + bs 84 if end > len(input) { 85 end = len(input) 86 } 87 n, err := encoder.Write(input[pos:end]) 88 testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil)) 89 testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos) 90 } 91 err := encoder.Close() 92 testEqual(t, "Close gave error %v, want %v", err, error(nil)) 93 testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded) 94 } 95 } 96 97 func TestDecode(t *testing.T) { 98 for _, p := range pairs { 99 dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded))) 100 count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded)) 101 testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil)) 102 testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded)) 103 if len(p.encoded) > 0 { 104 testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '=')) 105 } 106 testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded) 107 108 dbuf, err = StdEncoding.DecodeString(p.encoded) 109 testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil)) 110 testEqual(t, "DecodeString(%q) = %q, want %q", string(dbuf), p.decoded) 111 } 112 } 113 114 func TestDecoder(t *testing.T) { 115 for _, p := range pairs { 116 decoder := NewDecoder(StdEncoding, bytes.NewBufferString(p.encoded)) 117 dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded))) 118 count, err := decoder.Read(dbuf) 119 if err != nil && err != io.EOF { 120 t.Fatal("Read failed", err) 121 } 122 testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded)) 123 testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded) 124 if err != io.EOF { 125 count, err = decoder.Read(dbuf) 126 } 127 testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF) 128 } 129 } 130 131 func TestDecoderBuffering(t *testing.T) { 132 for bs := 1; bs <= 12; bs++ { 133 decoder := NewDecoder(StdEncoding, bytes.NewBufferString(bigtest.encoded)) 134 buf := make([]byte, len(bigtest.decoded)+12) 135 var total int 136 for total = 0; total < len(bigtest.decoded); { 137 n, err := decoder.Read(buf[total : total+bs]) 138 testEqual(t, "Read from %q at pos %d = %d, %v, want _, %v", bigtest.encoded, total, n, err, error(nil)) 139 total += n 140 } 141 testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded) 142 } 143 } 144 145 func TestDecodeCorrupt(t *testing.T) { 146 testCases := []struct { 147 input string 148 offset int // -1 means no corruption. 149 }{ 150 {"", -1}, 151 {"!!!!", 0}, 152 {"x===", 1}, 153 {"AA=A", 2}, 154 {"AAA=AAAA", 3}, 155 {"AAAAA", 4}, 156 {"AAAAAA", 4}, 157 {"A=", 1}, 158 {"A==", 1}, 159 {"AA=", 3}, 160 {"AA==", -1}, 161 {"AAA=", -1}, 162 {"AAAA", -1}, 163 {"AAAAAA=", 7}, 164 } 165 for _, tc := range testCases { 166 dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input))) 167 _, err := StdEncoding.Decode(dbuf, []byte(tc.input)) 168 if tc.offset == -1 { 169 if err != nil { 170 t.Error("Decoder wrongly detected coruption in", tc.input) 171 } 172 continue 173 } 174 switch err := err.(type) { 175 case CorruptInputError: 176 testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset) 177 default: 178 t.Error("Decoder failed to detect corruption in", tc) 179 } 180 } 181 } 182 183 func TestBig(t *testing.T) { 184 n := 3*1000 + 1 185 raw := make([]byte, n) 186 const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 187 for i := 0; i < n; i++ { 188 raw[i] = alpha[i%len(alpha)] 189 } 190 encoded := new(bytes.Buffer) 191 w := NewEncoder(StdEncoding, encoded) 192 nn, err := w.Write(raw) 193 if nn != n || err != nil { 194 t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n) 195 } 196 err = w.Close() 197 if err != nil { 198 t.Fatalf("Encoder.Close() = %v want nil", err) 199 } 200 decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded)) 201 if err != nil { 202 t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err) 203 } 204 205 if !bytes.Equal(raw, decoded) { 206 var i int 207 for i = 0; i < len(decoded) && i < len(raw); i++ { 208 if decoded[i] != raw[i] { 209 break 210 } 211 } 212 t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i) 213 } 214 } 215 216 func TestNewLineCharacters(t *testing.T) { 217 // Each of these should decode to the string "sure", without errors. 218 const expected = "sure" 219 examples := []string{ 220 "c3VyZQ==", 221 "c3VyZQ==\r", 222 "c3VyZQ==\n", 223 "c3VyZQ==\r\n", 224 "c3VyZ\r\nQ==", 225 "c3V\ryZ\nQ==", 226 "c3V\nyZ\rQ==", 227 "c3VyZ\nQ==", 228 "c3VyZQ\n==", 229 "c3VyZQ=\n=", 230 "c3VyZQ=\r\n\r\n=", 231 } 232 for _, e := range examples { 233 buf, err := StdEncoding.DecodeString(e) 234 if err != nil { 235 t.Errorf("Decode(%q) failed: %v", e, err) 236 continue 237 } 238 if s := string(buf); s != expected { 239 t.Errorf("Decode(%q) = %q, want %q", e, s, expected) 240 } 241 } 242 } 243 244 type nextRead struct { 245 n int // bytes to return 246 err error // error to return 247 } 248 249 // faultInjectReader returns data from source, rate-limited 250 // and with the errors as written to nextc. 251 type faultInjectReader struct { 252 source string 253 nextc <-chan nextRead 254 } 255 256 func (r *faultInjectReader) Read(p []byte) (int, error) { 257 nr := <-r.nextc 258 if len(p) > nr.n { 259 p = p[:nr.n] 260 } 261 n := copy(p, r.source) 262 r.source = r.source[n:] 263 return n, nr.err 264 } 265 266 // tests that we don't ignore errors from our underlying reader 267 func TestDecoderIssue3577(t *testing.T) { 268 next := make(chan nextRead, 10) 269 wantErr := errors.New("my error") 270 next <- nextRead{5, nil} 271 next <- nextRead{10, wantErr} 272 next <- nextRead{0, wantErr} 273 d := NewDecoder(StdEncoding, &faultInjectReader{ 274 source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig... 275 nextc: next, 276 }) 277 errc := make(chan error) 278 go func() { 279 _, err := ioutil.ReadAll(d) 280 errc <- err 281 }() 282 select { 283 case err := <-errc: 284 if err != wantErr { 285 t.Errorf("got error %v; want %v", err, wantErr) 286 } 287 case <-time.After(5 * time.Second): 288 t.Errorf("timeout; Decoder blocked without returning an error") 289 } 290 } 291 292 func TestDecoderIssue4779(t *testing.T) { 293 encoded := `CP/EAT8AAAEF 294 AQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAAB 295 BAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHx 296 Y3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm 297 9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS 298 0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0 299 pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkJ+Tj 300 1kiy1jCJJDnAcCTykpKkuQ6p/jN6FgmxlNduXawwAzaGH+V6jn/R/wCt71zdn+N/qL3kVYFNYB4N 301 ji6PDVjWpKp9TSXnvTf8bFNjg3qOEa2n6VlLpj/rT/pf567DpX1i6L1hs9Py67X8mqdtg/rUWbbf 302 +gkp0kkkklKSSSSUpJJJJT//0PVUkkklKVLq3WMDpGI7KzrNjADtYNXvI/Mqr/Pd/q9W3vaxjnvM 303 NaCXE9gNSvGPrf8AWS3qmba5jjsJhoB0DAf0NDf6sevf+/lf8Hj0JJATfWT6/dV6oXU1uOLQeKKn 304 EQP+Hubtfe/+R7Mf/g7f5xcocp++Z11JMCJPgFBxOg7/AOuqDx8I/ikpkXkmSdU8mJIJA/O8EMAy 305 j+mSARB/17pKVXYWHXjsj7yIex0PadzXMO1zT5KHoNA3HT8ietoGhgjsfA+CSnvvqh/jJtqsrwOv 306 2b6NGNzXfTYexzJ+nU7/ALkf4P8Awv6P9KvTQQ4AgyDqCF85Pho3CTB7eHwXoH+LT65uZbX9X+o2 307 bqbPb06551Y4 308 ` 309 encodedShort := strings.Replace(encoded, "\n", "", -1) 310 311 dec := NewDecoder(StdEncoding, bytes.NewBufferString(encoded)) 312 res1, err := ioutil.ReadAll(dec) 313 if err != nil { 314 t.Errorf("ReadAll failed: %v", err) 315 } 316 317 dec = NewDecoder(StdEncoding, bytes.NewBufferString(encodedShort)) 318 var res2 []byte 319 res2, err = ioutil.ReadAll(dec) 320 if err != nil { 321 t.Errorf("ReadAll failed: %v", err) 322 } 323 324 if !bytes.Equal(res1, res2) { 325 t.Error("Decoded results not equal") 326 } 327 }