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