libgo: update to go1.9
[official-gcc.git] / libgo / go / encoding / base32 / base32_test.go
blob56b229d15a6eee1bd45d43a4c440f79544e5235c
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 base32
7 import (
8 "bytes"
9 "errors"
10 "io"
11 "io/ioutil"
12 "strings"
13 "testing"
16 type testpair struct {
17 decoded, encoded string
20 var pairs = []testpair{
21 // RFC 4648 examples
22 {"", ""},
23 {"f", "MY======"},
24 {"fo", "MZXQ===="},
25 {"foo", "MZXW6==="},
26 {"foob", "MZXW6YQ="},
27 {"fooba", "MZXW6YTB"},
28 {"foobar", "MZXW6YTBOI======"},
30 // Wikipedia examples, converted to base32
31 {"sure.", "ON2XEZJO"},
32 {"sure", "ON2XEZI="},
33 {"sur", "ON2XE==="},
34 {"su", "ON2Q===="},
35 {"leasure.", "NRSWC43VOJSS4==="},
36 {"easure.", "MVQXG5LSMUXA===="},
37 {"asure.", "MFZXK4TFFY======"},
38 {"sure.", "ON2XEZJO"},
41 var bigtest = testpair{
42 "Twas brillig, and the slithy toves",
43 "KR3WC4ZAMJZGS3DMNFTSYIDBNZSCA5DIMUQHG3DJORUHSIDUN53GK4Y=",
46 func testEqual(t *testing.T, msg string, args ...interface{}) bool {
47 t.Helper()
48 if args[len(args)-2] != args[len(args)-1] {
49 t.Errorf(msg, args...)
50 return false
52 return true
55 func TestEncode(t *testing.T) {
56 for _, p := range pairs {
57 got := StdEncoding.EncodeToString([]byte(p.decoded))
58 testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
62 func TestEncoder(t *testing.T) {
63 for _, p := range pairs {
64 bb := &bytes.Buffer{}
65 encoder := NewEncoder(StdEncoding, bb)
66 encoder.Write([]byte(p.decoded))
67 encoder.Close()
68 testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
72 func TestEncoderBuffering(t *testing.T) {
73 input := []byte(bigtest.decoded)
74 for bs := 1; bs <= 12; bs++ {
75 bb := &bytes.Buffer{}
76 encoder := NewEncoder(StdEncoding, bb)
77 for pos := 0; pos < len(input); pos += bs {
78 end := pos + bs
79 if end > len(input) {
80 end = len(input)
82 n, err := encoder.Write(input[pos:end])
83 testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
84 testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
86 err := encoder.Close()
87 testEqual(t, "Close gave error %v, want %v", err, error(nil))
88 testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
92 func TestDecode(t *testing.T) {
93 for _, p := range pairs {
94 dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
95 count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
96 testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
97 testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
98 if len(p.encoded) > 0 {
99 testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
101 testEqual(t, "Decode(%q) = %q, want %q", p.encoded,
102 string(dbuf[0:count]),
103 p.decoded)
105 dbuf, err = StdEncoding.DecodeString(p.encoded)
106 testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
107 testEqual(t, "DecodeString(%q) = %q, want %q", p.encoded, string(dbuf), p.decoded)
111 func TestDecoder(t *testing.T) {
112 for _, p := range pairs {
113 decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
114 dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
115 count, err := decoder.Read(dbuf)
116 if err != nil && err != io.EOF {
117 t.Fatal("Read failed", err)
119 testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
120 testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
121 if err != io.EOF {
122 count, err = decoder.Read(dbuf)
124 testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
128 type badReader struct {
129 data []byte
130 errs []error
131 called int
132 limit int
135 // Populates p with data, returns a count of the bytes written and an
136 // error. The error returned is taken from badReader.errs, with each
137 // invocation of Read returning the next error in this slice, or io.EOF,
138 // if all errors from the slice have already been returned. The
139 // number of bytes returned is determined by the size of the input buffer
140 // the test passes to decoder.Read and will be a multiple of 8, unless
141 // badReader.limit is non zero.
142 func (b *badReader) Read(p []byte) (int, error) {
143 lim := len(p)
144 if b.limit != 0 && b.limit < lim {
145 lim = b.limit
147 if len(b.data) < lim {
148 lim = len(b.data)
150 for i := range p[:lim] {
151 p[i] = b.data[i]
153 b.data = b.data[lim:]
154 err := io.EOF
155 if b.called < len(b.errs) {
156 err = b.errs[b.called]
158 b.called++
159 return lim, err
162 // TestIssue20044 tests that decoder.Read behaves correctly when the caller
163 // supplied reader returns an error.
164 func TestIssue20044(t *testing.T) {
165 badErr := errors.New("bad reader error")
166 testCases := []struct {
167 r badReader
168 res string
169 err error
170 dbuflen int
172 // Check valid input data accompanied by an error is processed and the error is propagated.
173 {r: badReader{data: []byte("MY======"), errs: []error{badErr}},
174 res: "f", err: badErr},
175 // Check a read error accompanied by input data consisting of newlines only is propagated.
176 {r: badReader{data: []byte("\n\n\n\n\n\n\n\n"), errs: []error{badErr, nil}},
177 res: "", err: badErr},
178 // Reader will be called twice. The first time it will return 8 newline characters. The
179 // second time valid base32 encoded data and an error. The data should be decoded
180 // correctly and the error should be propagated.
181 {r: badReader{data: []byte("\n\n\n\n\n\n\n\nMY======"), errs: []error{nil, badErr}},
182 res: "f", err: badErr, dbuflen: 8},
183 // Reader returns invalid input data (too short) and an error. Verify the reader
184 // error is returned.
185 {r: badReader{data: []byte("MY====="), errs: []error{badErr}},
186 res: "", err: badErr},
187 // Reader returns invalid input data (too short) but no error. Verify io.ErrUnexpectedEOF
188 // is returned.
189 {r: badReader{data: []byte("MY====="), errs: []error{nil}},
190 res: "", err: io.ErrUnexpectedEOF},
191 // Reader returns invalid input data and an error. Verify the reader and not the
192 // decoder error is returned.
193 {r: badReader{data: []byte("Ma======"), errs: []error{badErr}},
194 res: "", err: badErr},
195 // Reader returns valid data and io.EOF. Check data is decoded and io.EOF is propagated.
196 {r: badReader{data: []byte("MZXW6YTB"), errs: []error{io.EOF}},
197 res: "fooba", err: io.EOF},
198 // Check errors are properly reported when decoder.Read is called multiple times.
199 // decoder.Read will be called 8 times, badReader.Read will be called twice, returning
200 // valid data both times but an error on the second call.
201 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{nil, badErr}},
202 res: "leasure.", err: badErr, dbuflen: 1},
203 // Check io.EOF is properly reported when decoder.Read is called multiple times.
204 // decoder.Read will be called 8 times, badReader.Read will be called twice, returning
205 // valid data both times but io.EOF on the second call.
206 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{nil, io.EOF}},
207 res: "leasure.", err: io.EOF, dbuflen: 1},
208 // The following two test cases check that errors are propagated correctly when more than
209 // 8 bytes are read at a time.
210 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{io.EOF}},
211 res: "leasure.", err: io.EOF, dbuflen: 11},
212 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{badErr}},
213 res: "leasure.", err: badErr, dbuflen: 11},
214 // Check that errors are correctly propagated when the reader returns valid bytes in
215 // groups that are not divisible by 8. The first read will return 11 bytes and no
216 // error. The second will return 7 and an error. The data should be decoded correctly
217 // and the error should be propagated.
218 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{nil, badErr}, limit: 11},
219 res: "leasure.", err: badErr},
222 for _, tc := range testCases {
223 input := tc.r.data
224 decoder := NewDecoder(StdEncoding, &tc.r)
225 var dbuflen int
226 if tc.dbuflen > 0 {
227 dbuflen = tc.dbuflen
228 } else {
229 dbuflen = StdEncoding.DecodedLen(len(input))
231 dbuf := make([]byte, dbuflen)
232 var err error
233 var res []byte
234 for err == nil {
235 var n int
236 n, err = decoder.Read(dbuf)
237 if n > 0 {
238 res = append(res, dbuf[:n]...)
242 testEqual(t, "Decoding of %q = %q, want %q", string(input), string(res), tc.res)
243 testEqual(t, "Decoding of %q err = %v, expected %v", string(input), err, tc.err)
247 // TestDecoderError verifies decode errors are propagated when there are no read
248 // errors.
249 func TestDecoderError(t *testing.T) {
250 for _, readErr := range []error{io.EOF, nil} {
251 input := "MZXW6YTb"
252 dbuf := make([]byte, StdEncoding.DecodedLen(len(input)))
253 br := badReader{data: []byte(input), errs: []error{readErr}}
254 decoder := NewDecoder(StdEncoding, &br)
255 n, err := decoder.Read(dbuf)
256 testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
257 if _, ok := err.(CorruptInputError); !ok {
258 t.Errorf("Corrupt input error expected. Found %T", err)
263 // TestReaderEOF ensures decoder.Read behaves correctly when input data is
264 // exhausted.
265 func TestReaderEOF(t *testing.T) {
266 for _, readErr := range []error{io.EOF, nil} {
267 input := "MZXW6YTB"
268 br := badReader{data: []byte(input), errs: []error{nil, readErr}}
269 decoder := NewDecoder(StdEncoding, &br)
270 dbuf := make([]byte, StdEncoding.DecodedLen(len(input)))
271 n, err := decoder.Read(dbuf)
272 testEqual(t, "Decoding of %q err = %v, expected %v", string(input), err, error(nil))
273 n, err = decoder.Read(dbuf)
274 testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
275 testEqual(t, "Read after EOF, err = %v, expected %v", err, io.EOF)
276 n, err = decoder.Read(dbuf)
277 testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
278 testEqual(t, "Read after EOF, err = %v, expected %v", err, io.EOF)
282 func TestDecoderBuffering(t *testing.T) {
283 for bs := 1; bs <= 12; bs++ {
284 decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
285 buf := make([]byte, len(bigtest.decoded)+12)
286 var total int
287 var n int
288 var err error
289 for total = 0; total < len(bigtest.decoded) && err == nil; {
290 n, err = decoder.Read(buf[total : total+bs])
291 total += n
293 if err != nil && err != io.EOF {
294 t.Errorf("Read from %q at pos %d = %d, unexpected error %v", bigtest.encoded, total, n, err)
296 testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
300 func TestDecodeCorrupt(t *testing.T) {
301 testCases := []struct {
302 input string
303 offset int // -1 means no corruption.
305 {"", -1},
306 {"!!!!", 0},
307 {"x===", 0},
308 {"AA=A====", 2},
309 {"AAA=AAAA", 3},
310 {"MMMMMMMMM", 8},
311 {"MMMMMM", 0},
312 {"A=", 1},
313 {"AA=", 3},
314 {"AA==", 4},
315 {"AA===", 5},
316 {"AAAA=", 5},
317 {"AAAA==", 6},
318 {"AAAAA=", 6},
319 {"AAAAA==", 7},
320 {"A=======", 1},
321 {"AA======", -1},
322 {"AAA=====", 3},
323 {"AAAA====", -1},
324 {"AAAAA===", -1},
325 {"AAAAAA==", 6},
326 {"AAAAAAA=", -1},
327 {"AAAAAAAA", -1},
329 for _, tc := range testCases {
330 dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
331 _, err := StdEncoding.Decode(dbuf, []byte(tc.input))
332 if tc.offset == -1 {
333 if err != nil {
334 t.Error("Decoder wrongly detected corruption in", tc.input)
336 continue
338 switch err := err.(type) {
339 case CorruptInputError:
340 testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
341 default:
342 t.Error("Decoder failed to detect corruption in", tc)
347 func TestBig(t *testing.T) {
348 n := 3*1000 + 1
349 raw := make([]byte, n)
350 const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
351 for i := 0; i < n; i++ {
352 raw[i] = alpha[i%len(alpha)]
354 encoded := new(bytes.Buffer)
355 w := NewEncoder(StdEncoding, encoded)
356 nn, err := w.Write(raw)
357 if nn != n || err != nil {
358 t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
360 err = w.Close()
361 if err != nil {
362 t.Fatalf("Encoder.Close() = %v want nil", err)
364 decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded))
365 if err != nil {
366 t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err)
369 if !bytes.Equal(raw, decoded) {
370 var i int
371 for i = 0; i < len(decoded) && i < len(raw); i++ {
372 if decoded[i] != raw[i] {
373 break
376 t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
380 func testStringEncoding(t *testing.T, expected string, examples []string) {
381 for _, e := range examples {
382 buf, err := StdEncoding.DecodeString(e)
383 if err != nil {
384 t.Errorf("Decode(%q) failed: %v", e, err)
385 continue
387 if s := string(buf); s != expected {
388 t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
393 func TestNewLineCharacters(t *testing.T) {
394 // Each of these should decode to the string "sure", without errors.
395 examples := []string{
396 "ON2XEZI=",
397 "ON2XEZI=\r",
398 "ON2XEZI=\n",
399 "ON2XEZI=\r\n",
400 "ON2XEZ\r\nI=",
401 "ON2X\rEZ\nI=",
402 "ON2X\nEZ\rI=",
403 "ON2XEZ\nI=",
404 "ON2XEZI\n=",
406 testStringEncoding(t, "sure", examples)
408 // Each of these should decode to the string "foobar", without errors.
409 examples = []string{
410 "MZXW6YTBOI======",
411 "MZXW6YTBOI=\r\n=====",
413 testStringEncoding(t, "foobar", examples)
416 func TestDecoderIssue4779(t *testing.T) {
417 encoded := `JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4
418 RAMFSGS4DJONUWG2LOM4QGK3DJOQWCA43FMQQGI3YKMVUXK43NN5SCA5DFNVYG64RANFXGG2LENFSH
419 K3TUEB2XIIDMMFRG64TFEBSXIIDEN5WG64TFEBWWCZ3OMEQGC3DJOF2WCLRAKV2CAZLONFWQUYLEEB
420 WWS3TJNUQHMZLONFQW2LBAOF2WS4ZANZXXG5DSOVSCAZLYMVZGG2LUMF2GS33OEB2WY3DBNVRW6IDM
421 MFRG64TJOMQG42LTNEQHK5AKMFWGS4LVNFYCAZLYEBSWCIDDN5WW233EN4QGG33OONSXC5LBOQXCAR
422 DVNFZSAYLVORSSA2LSOVZGKIDEN5WG64RANFXAU4TFOBZGK2DFNZSGK4TJOQQGS3RAOZXWY5LQORQX
423 IZJAOZSWY2LUEBSXG43FEBRWS3DMOVWSAZDPNRXXEZJAMV2SAZTVM5UWC5BANZ2WY3DBBJYGC4TJMF
424 2HK4ROEBCXQY3FOB2GK5LSEBZWS3TUEBXWGY3BMVRWC5BAMN2XA2LEMF2GC5BANZXW4IDQOJXWSZDF
425 NZ2CYIDTOVXHIIDJNYFGG5LMOBQSA4LVNEQG6ZTGNFRWSYJAMRSXGZLSOVXHIIDNN5WGY2LUEBQW42
426 LNEBUWIIDFON2CA3DBMJXXE5LNFY==
427 ====`
428 encodedShort := strings.Replace(encoded, "\n", "", -1)
430 dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
431 res1, err := ioutil.ReadAll(dec)
432 if err != nil {
433 t.Errorf("ReadAll failed: %v", err)
436 dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
437 var res2 []byte
438 res2, err = ioutil.ReadAll(dec)
439 if err != nil {
440 t.Errorf("ReadAll failed: %v", err)
443 if !bytes.Equal(res1, res2) {
444 t.Error("Decoded results not equal")
448 func BenchmarkEncodeToString(b *testing.B) {
449 data := make([]byte, 8192)
450 b.SetBytes(int64(len(data)))
451 for i := 0; i < b.N; i++ {
452 StdEncoding.EncodeToString(data)
456 func BenchmarkDecodeString(b *testing.B) {
457 data := StdEncoding.EncodeToString(make([]byte, 8192))
458 b.SetBytes(int64(len(data)))
459 for i := 0; i < b.N; i++ {
460 StdEncoding.DecodeString(data)
464 func TestWithCustomPadding(t *testing.T) {
465 for _, testcase := range pairs {
466 defaultPadding := StdEncoding.EncodeToString([]byte(testcase.decoded))
467 customPadding := StdEncoding.WithPadding('@').EncodeToString([]byte(testcase.decoded))
468 expected := strings.Replace(defaultPadding, "=", "@", -1)
470 if expected != customPadding {
471 t.Errorf("Expected custom %s, got %s", expected, customPadding)
473 if testcase.encoded != defaultPadding {
474 t.Errorf("Expected %s, got %s", testcase.encoded, defaultPadding)
479 func TestWithoutPadding(t *testing.T) {
480 for _, testcase := range pairs {
481 defaultPadding := StdEncoding.EncodeToString([]byte(testcase.decoded))
482 customPadding := StdEncoding.WithPadding(NoPadding).EncodeToString([]byte(testcase.decoded))
483 expected := strings.TrimRight(defaultPadding, "=")
485 if expected != customPadding {
486 t.Errorf("Expected custom %s, got %s", expected, customPadding)
488 if testcase.encoded != defaultPadding {
489 t.Errorf("Expected %s, got %s", testcase.encoded, defaultPadding)
494 func TestDecodeWithPadding(t *testing.T) {
495 encodings := []*Encoding{
496 StdEncoding,
497 StdEncoding.WithPadding('-'),
498 StdEncoding.WithPadding(NoPadding),
501 for i, enc := range encodings {
502 for _, pair := range pairs {
504 input := pair.decoded
505 encoded := enc.EncodeToString([]byte(input))
507 decoded, err := enc.DecodeString(encoded)
508 if err != nil {
509 t.Errorf("DecodeString Error for encoding %d (%q): %v", i, input, err)
512 if input != string(decoded) {
513 t.Errorf("Unexpected result for encoding %d: got %q; want %q", i, decoded, input)
519 func TestDecodeWithWrongPadding(t *testing.T) {
520 encoded := StdEncoding.EncodeToString([]byte("foobar"))
522 _, err := StdEncoding.WithPadding('-').DecodeString(encoded)
523 if err == nil {
524 t.Error("expected error")
527 _, err = StdEncoding.WithPadding(NoPadding).DecodeString(encoded)
528 if err == nil {
529 t.Error("expected error")
533 func TestEncodedDecodedLen(t *testing.T) {
534 type test struct {
535 in int
536 wantEnc int
537 wantDec int
539 data := bytes.Repeat([]byte("x"), 100)
540 for _, test := range []struct {
541 name string
542 enc *Encoding
543 cases []test
545 {"StdEncoding", StdEncoding, []test{
546 {0, 0, 0},
547 {1, 8, 5},
548 {5, 8, 5},
549 {6, 16, 10},
550 {10, 16, 10},
552 {"NoPadding", StdEncoding.WithPadding(NoPadding), []test{
553 {0, 0, 0},
554 {1, 2, 1},
555 {2, 4, 2},
556 {5, 8, 5},
557 {6, 10, 6},
558 {7, 12, 7},
559 {10, 16, 10},
560 {11, 18, 11},
563 t.Run(test.name, func(t *testing.T) {
564 for _, tc := range test.cases {
565 encLen := test.enc.EncodedLen(tc.in)
566 decLen := test.enc.DecodedLen(encLen)
567 enc := test.enc.EncodeToString(data[:tc.in])
568 if len(enc) != encLen {
569 t.Fatalf("EncodedLen(%d) = %d but encoded to %q (%d)", tc.in, encLen, enc, len(enc))
571 if encLen != tc.wantEnc {
572 t.Fatalf("EncodedLen(%d) = %d; want %d", tc.in, encLen, tc.wantEnc)
574 if decLen != tc.wantDec {
575 t.Fatalf("DecodedLen(%d) = %d; want %d", encLen, decLen, tc.wantDec)