1
2
3
4
5 package base32
6
7 import (
8 "bytes"
9 "errors"
10 "io"
11 "strings"
12 "testing"
13 )
14
15 type testpair struct {
16 decoded, encoded string
17 }
18
19 var pairs = []testpair{
20
21 {"", ""},
22 {"f", "MY======"},
23 {"fo", "MZXQ===="},
24 {"foo", "MZXW6==="},
25 {"foob", "MZXW6YQ="},
26 {"fooba", "MZXW6YTB"},
27 {"foobar", "MZXW6YTBOI======"},
28
29
30 {"sure.", "ON2XEZJO"},
31 {"sure", "ON2XEZI="},
32 {"sur", "ON2XE==="},
33 {"su", "ON2Q===="},
34 {"leasure.", "NRSWC43VOJSS4==="},
35 {"easure.", "MVQXG5LSMUXA===="},
36 {"asure.", "MFZXK4TFFY======"},
37 {"sure.", "ON2XEZJO"},
38 }
39
40 var bigtest = testpair{
41 "Twas brillig, and the slithy toves",
42 "KR3WC4ZAMJZGS3DMNFTSYIDBNZSCA5DIMUQHG3DJORUHSIDUN53GK4Y=",
43 }
44
45 func testEqual(t *testing.T, msg string, args ...any) bool {
46 t.Helper()
47 if args[len(args)-2] != args[len(args)-1] {
48 t.Errorf(msg, args...)
49 return false
50 }
51 return true
52 }
53
54 func TestEncode(t *testing.T) {
55 for _, p := range pairs {
56 got := StdEncoding.EncodeToString([]byte(p.decoded))
57 testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
58 }
59 }
60
61 func TestEncoder(t *testing.T) {
62 for _, p := range pairs {
63 bb := &bytes.Buffer{}
64 encoder := NewEncoder(StdEncoding, bb)
65 encoder.Write([]byte(p.decoded))
66 encoder.Close()
67 testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
68 }
69 }
70
71 func TestEncoderBuffering(t *testing.T) {
72 input := []byte(bigtest.decoded)
73 for bs := 1; bs <= 12; bs++ {
74 bb := &bytes.Buffer{}
75 encoder := NewEncoder(StdEncoding, bb)
76 for pos := 0; pos < len(input); pos += bs {
77 end := pos + bs
78 if end > len(input) {
79 end = len(input)
80 }
81 n, err := encoder.Write(input[pos:end])
82 testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
83 testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
84 }
85 err := encoder.Close()
86 testEqual(t, "Close gave error %v, want %v", err, error(nil))
87 testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
88 }
89 }
90
91 func TestDecode(t *testing.T) {
92 for _, p := range pairs {
93 dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
94 count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
95 testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
96 testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
97 if len(p.encoded) > 0 {
98 testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
99 }
100 testEqual(t, "Decode(%q) = %q, want %q", p.encoded,
101 string(dbuf[0:count]),
102 p.decoded)
103
104 dbuf, err = StdEncoding.DecodeString(p.encoded)
105 testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
106 testEqual(t, "DecodeString(%q) = %q, want %q", p.encoded, string(dbuf), p.decoded)
107 }
108 }
109
110 func TestDecoder(t *testing.T) {
111 for _, p := range pairs {
112 decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
113 dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
114 count, err := decoder.Read(dbuf)
115 if err != nil && err != io.EOF {
116 t.Fatal("Read failed", err)
117 }
118 testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
119 testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
120 if err != io.EOF {
121 _, err = decoder.Read(dbuf)
122 }
123 testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
124 }
125 }
126
127 type badReader struct {
128 data []byte
129 errs []error
130 called int
131 limit int
132 }
133
134
135
136
137
138
139
140
141 func (b *badReader) Read(p []byte) (int, error) {
142 lim := len(p)
143 if b.limit != 0 && b.limit < lim {
144 lim = b.limit
145 }
146 if len(b.data) < lim {
147 lim = len(b.data)
148 }
149 for i := range p[:lim] {
150 p[i] = b.data[i]
151 }
152 b.data = b.data[lim:]
153 err := io.EOF
154 if b.called < len(b.errs) {
155 err = b.errs[b.called]
156 }
157 b.called++
158 return lim, err
159 }
160
161
162
163 func TestIssue20044(t *testing.T) {
164 badErr := errors.New("bad reader error")
165 testCases := []struct {
166 r badReader
167 res string
168 err error
169 dbuflen int
170 }{
171
172 {r: badReader{data: []byte("MY======"), errs: []error{badErr}},
173 res: "f", err: badErr},
174
175 {r: badReader{data: []byte("\n\n\n\n\n\n\n\n"), errs: []error{badErr, nil}},
176 res: "", err: badErr},
177
178
179
180 {r: badReader{data: []byte("\n\n\n\n\n\n\n\nMY======"), errs: []error{nil, badErr}},
181 res: "f", err: badErr, dbuflen: 8},
182
183
184 {r: badReader{data: []byte("MY====="), errs: []error{badErr}},
185 res: "", err: badErr},
186
187
188 {r: badReader{data: []byte("MY====="), errs: []error{nil}},
189 res: "", err: io.ErrUnexpectedEOF},
190
191
192 {r: badReader{data: []byte("Ma======"), errs: []error{badErr}},
193 res: "", err: badErr},
194
195 {r: badReader{data: []byte("MZXW6YTB"), errs: []error{io.EOF}},
196 res: "fooba", err: io.EOF},
197
198
199
200 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{nil, badErr}},
201 res: "leasure.", err: badErr, dbuflen: 1},
202
203
204
205 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{nil, io.EOF}},
206 res: "leasure.", err: io.EOF, dbuflen: 1},
207
208
209 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{io.EOF}},
210 res: "leasure.", err: io.EOF, dbuflen: 11},
211 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{badErr}},
212 res: "leasure.", err: badErr, dbuflen: 11},
213
214
215
216
217 {r: badReader{data: []byte("NRSWC43VOJSS4==="), errs: []error{nil, badErr}, limit: 11},
218 res: "leasure.", err: badErr},
219 }
220
221 for _, tc := range testCases {
222 input := tc.r.data
223 decoder := NewDecoder(StdEncoding, &tc.r)
224 var dbuflen int
225 if tc.dbuflen > 0 {
226 dbuflen = tc.dbuflen
227 } else {
228 dbuflen = StdEncoding.DecodedLen(len(input))
229 }
230 dbuf := make([]byte, dbuflen)
231 var err error
232 var res []byte
233 for err == nil {
234 var n int
235 n, err = decoder.Read(dbuf)
236 if n > 0 {
237 res = append(res, dbuf[:n]...)
238 }
239 }
240
241 testEqual(t, "Decoding of %q = %q, want %q", string(input), string(res), tc.res)
242 testEqual(t, "Decoding of %q err = %v, expected %v", string(input), err, tc.err)
243 }
244 }
245
246
247
248 func TestDecoderError(t *testing.T) {
249 for _, readErr := range []error{io.EOF, nil} {
250 input := "MZXW6YTb"
251 dbuf := make([]byte, StdEncoding.DecodedLen(len(input)))
252 br := badReader{data: []byte(input), errs: []error{readErr}}
253 decoder := NewDecoder(StdEncoding, &br)
254 n, err := decoder.Read(dbuf)
255 testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
256 if _, ok := err.(CorruptInputError); !ok {
257 t.Errorf("Corrupt input error expected. Found %T", err)
258 }
259 }
260 }
261
262
263
264 func TestReaderEOF(t *testing.T) {
265 for _, readErr := range []error{io.EOF, nil} {
266 input := "MZXW6YTB"
267 br := badReader{data: []byte(input), errs: []error{nil, readErr}}
268 decoder := NewDecoder(StdEncoding, &br)
269 dbuf := make([]byte, StdEncoding.DecodedLen(len(input)))
270 n, err := decoder.Read(dbuf)
271 testEqual(t, "Decoding of %q err = %v, expected %v", string(input), err, error(nil))
272 n, err = decoder.Read(dbuf)
273 testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
274 testEqual(t, "Read after EOF, err = %v, expected %v", err, io.EOF)
275 n, err = decoder.Read(dbuf)
276 testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
277 testEqual(t, "Read after EOF, err = %v, expected %v", err, io.EOF)
278 }
279 }
280
281 func TestDecoderBuffering(t *testing.T) {
282 for bs := 1; bs <= 12; bs++ {
283 decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
284 buf := make([]byte, len(bigtest.decoded)+12)
285 var total int
286 var n int
287 var err error
288 for total = 0; total < len(bigtest.decoded) && err == nil; {
289 n, err = decoder.Read(buf[total : total+bs])
290 total += n
291 }
292 if err != nil && err != io.EOF {
293 t.Errorf("Read from %q at pos %d = %d, unexpected error %v", bigtest.encoded, total, n, err)
294 }
295 testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
296 }
297 }
298
299 func TestDecodeCorrupt(t *testing.T) {
300 testCases := []struct {
301 input string
302 offset int
303 }{
304 {"", -1},
305 {"!!!!", 0},
306 {"x===", 0},
307 {"AA=A====", 2},
308 {"AAA=AAAA", 3},
309 {"MMMMMMMMM", 8},
310 {"MMMMMM", 0},
311 {"A=", 1},
312 {"AA=", 3},
313 {"AA==", 4},
314 {"AA===", 5},
315 {"AAAA=", 5},
316 {"AAAA==", 6},
317 {"AAAAA=", 6},
318 {"AAAAA==", 7},
319 {"A=======", 1},
320 {"AA======", -1},
321 {"AAA=====", 3},
322 {"AAAA====", -1},
323 {"AAAAA===", -1},
324 {"AAAAAA==", 6},
325 {"AAAAAAA=", -1},
326 {"AAAAAAAA", -1},
327 }
328 for _, tc := range testCases {
329 dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
330 _, err := StdEncoding.Decode(dbuf, []byte(tc.input))
331 if tc.offset == -1 {
332 if err != nil {
333 t.Error("Decoder wrongly detected corruption in", tc.input)
334 }
335 continue
336 }
337 switch err := err.(type) {
338 case CorruptInputError:
339 testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
340 default:
341 t.Error("Decoder failed to detect corruption in", tc)
342 }
343 }
344 }
345
346 func TestBig(t *testing.T) {
347 n := 3*1000 + 1
348 raw := make([]byte, n)
349 const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
350 for i := 0; i < n; i++ {
351 raw[i] = alpha[i%len(alpha)]
352 }
353 encoded := new(bytes.Buffer)
354 w := NewEncoder(StdEncoding, encoded)
355 nn, err := w.Write(raw)
356 if nn != n || err != nil {
357 t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
358 }
359 err = w.Close()
360 if err != nil {
361 t.Fatalf("Encoder.Close() = %v want nil", err)
362 }
363 decoded, err := io.ReadAll(NewDecoder(StdEncoding, encoded))
364 if err != nil {
365 t.Fatalf("io.ReadAll(NewDecoder(...)): %v", err)
366 }
367
368 if !bytes.Equal(raw, decoded) {
369 var i int
370 for i = 0; i < len(decoded) && i < len(raw); i++ {
371 if decoded[i] != raw[i] {
372 break
373 }
374 }
375 t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
376 }
377 }
378
379 func testStringEncoding(t *testing.T, expected string, examples []string) {
380 for _, e := range examples {
381 buf, err := StdEncoding.DecodeString(e)
382 if err != nil {
383 t.Errorf("Decode(%q) failed: %v", e, err)
384 continue
385 }
386 if s := string(buf); s != expected {
387 t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
388 }
389 }
390 }
391
392 func TestNewLineCharacters(t *testing.T) {
393
394 examples := []string{
395 "ON2XEZI=",
396 "ON2XEZI=\r",
397 "ON2XEZI=\n",
398 "ON2XEZI=\r\n",
399 "ON2XEZ\r\nI=",
400 "ON2X\rEZ\nI=",
401 "ON2X\nEZ\rI=",
402 "ON2XEZ\nI=",
403 "ON2XEZI\n=",
404 }
405 testStringEncoding(t, "sure", examples)
406
407
408 examples = []string{
409 "MZXW6YTBOI======",
410 "MZXW6YTBOI=\r\n=====",
411 }
412 testStringEncoding(t, "foobar", examples)
413 }
414
415 func TestDecoderIssue4779(t *testing.T) {
416 encoded := `JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4
417 RAMFSGS4DJONUWG2LOM4QGK3DJOQWCA43FMQQGI3YKMVUXK43NN5SCA5DFNVYG64RANFXGG2LENFSH
418 K3TUEB2XIIDMMFRG64TFEBSXIIDEN5WG64TFEBWWCZ3OMEQGC3DJOF2WCLRAKV2CAZLONFWQUYLEEB
419 WWS3TJNUQHMZLONFQW2LBAOF2WS4ZANZXXG5DSOVSCAZLYMVZGG2LUMF2GS33OEB2WY3DBNVRW6IDM
420 MFRG64TJOMQG42LTNEQHK5AKMFWGS4LVNFYCAZLYEBSWCIDDN5WW233EN4QGG33OONSXC5LBOQXCAR
421 DVNFZSAYLVORSSA2LSOVZGKIDEN5WG64RANFXAU4TFOBZGK2DFNZSGK4TJOQQGS3RAOZXWY5LQORQX
422 IZJAOZSWY2LUEBSXG43FEBRWS3DMOVWSAZDPNRXXEZJAMV2SAZTVM5UWC5BANZ2WY3DBBJYGC4TJMF
423 2HK4ROEBCXQY3FOB2GK5LSEBZWS3TUEBXWGY3BMVRWC5BAMN2XA2LEMF2GC5BANZXW4IDQOJXWSZDF
424 NZ2CYIDTOVXHIIDJNYFGG5LMOBQSA4LVNEQG6ZTGNFRWSYJAMRSXGZLSOVXHIIDNN5WGY2LUEBQW42
425 LNEBUWIIDFON2CA3DBMJXXE5LNFY==
426 ====`
427 encodedShort := strings.ReplaceAll(encoded, "\n", "")
428
429 dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
430 res1, err := io.ReadAll(dec)
431 if err != nil {
432 t.Errorf("ReadAll failed: %v", err)
433 }
434
435 dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
436 var res2 []byte
437 res2, err = io.ReadAll(dec)
438 if err != nil {
439 t.Errorf("ReadAll failed: %v", err)
440 }
441
442 if !bytes.Equal(res1, res2) {
443 t.Error("Decoded results not equal")
444 }
445 }
446
447 func BenchmarkEncode(b *testing.B) {
448 data := make([]byte, 8192)
449 buf := make([]byte, StdEncoding.EncodedLen(len(data)))
450 b.SetBytes(int64(len(data)))
451 for i := 0; i < b.N; i++ {
452 StdEncoding.Encode(buf, data)
453 }
454 }
455
456 func BenchmarkEncodeToString(b *testing.B) {
457 data := make([]byte, 8192)
458 b.SetBytes(int64(len(data)))
459 for i := 0; i < b.N; i++ {
460 StdEncoding.EncodeToString(data)
461 }
462 }
463
464 func BenchmarkDecode(b *testing.B) {
465 data := make([]byte, StdEncoding.EncodedLen(8192))
466 StdEncoding.Encode(data, make([]byte, 8192))
467 buf := make([]byte, 8192)
468 b.SetBytes(int64(len(data)))
469 for i := 0; i < b.N; i++ {
470 StdEncoding.Decode(buf, data)
471 }
472 }
473 func BenchmarkDecodeString(b *testing.B) {
474 data := StdEncoding.EncodeToString(make([]byte, 8192))
475 b.SetBytes(int64(len(data)))
476 for i := 0; i < b.N; i++ {
477 StdEncoding.DecodeString(data)
478 }
479 }
480
481 func TestWithCustomPadding(t *testing.T) {
482 for _, testcase := range pairs {
483 defaultPadding := StdEncoding.EncodeToString([]byte(testcase.decoded))
484 customPadding := StdEncoding.WithPadding('@').EncodeToString([]byte(testcase.decoded))
485 expected := strings.ReplaceAll(defaultPadding, "=", "@")
486
487 if expected != customPadding {
488 t.Errorf("Expected custom %s, got %s", expected, customPadding)
489 }
490 if testcase.encoded != defaultPadding {
491 t.Errorf("Expected %s, got %s", testcase.encoded, defaultPadding)
492 }
493 }
494 }
495
496 func TestWithoutPadding(t *testing.T) {
497 for _, testcase := range pairs {
498 defaultPadding := StdEncoding.EncodeToString([]byte(testcase.decoded))
499 customPadding := StdEncoding.WithPadding(NoPadding).EncodeToString([]byte(testcase.decoded))
500 expected := strings.TrimRight(defaultPadding, "=")
501
502 if expected != customPadding {
503 t.Errorf("Expected custom %s, got %s", expected, customPadding)
504 }
505 if testcase.encoded != defaultPadding {
506 t.Errorf("Expected %s, got %s", testcase.encoded, defaultPadding)
507 }
508 }
509 }
510
511 func TestDecodeWithPadding(t *testing.T) {
512 encodings := []*Encoding{
513 StdEncoding,
514 StdEncoding.WithPadding('-'),
515 StdEncoding.WithPadding(NoPadding),
516 }
517
518 for i, enc := range encodings {
519 for _, pair := range pairs {
520
521 input := pair.decoded
522 encoded := enc.EncodeToString([]byte(input))
523
524 decoded, err := enc.DecodeString(encoded)
525 if err != nil {
526 t.Errorf("DecodeString Error for encoding %d (%q): %v", i, input, err)
527 }
528
529 if input != string(decoded) {
530 t.Errorf("Unexpected result for encoding %d: got %q; want %q", i, decoded, input)
531 }
532 }
533 }
534 }
535
536 func TestDecodeWithWrongPadding(t *testing.T) {
537 encoded := StdEncoding.EncodeToString([]byte("foobar"))
538
539 _, err := StdEncoding.WithPadding('-').DecodeString(encoded)
540 if err == nil {
541 t.Error("expected error")
542 }
543
544 _, err = StdEncoding.WithPadding(NoPadding).DecodeString(encoded)
545 if err == nil {
546 t.Error("expected error")
547 }
548 }
549
550 func TestBufferedDecodingSameError(t *testing.T) {
551 testcases := []struct {
552 prefix string
553 chunkCombinations [][]string
554 expected error
555 }{
556
557
558 {"helloworld", [][]string{
559 {"NBSW", "Y3DP", "O5XX", "E3DE", "ZZ"},
560 {"NBSWY3DPO5XXE3DE", "ZZ"},
561 {"NBSWY3DPO5XXE3DEZZ"},
562 {"NBS", "WY3", "DPO", "5XX", "E3D", "EZZ"},
563 {"NBSWY3DPO5XXE3", "DEZZ"},
564 }, io.ErrUnexpectedEOF},
565
566
567 {"helloworld", [][]string{
568 {"NBSW", "Y3DP", "O5XX", "E3DE", "ZZY"},
569 {"NBSWY3DPO5XXE3DE", "ZZY"},
570 {"NBSWY3DPO5XXE3DEZZY"},
571 {"NBS", "WY3", "DPO", "5XX", "E3D", "EZZY"},
572 {"NBSWY3DPO5XXE3", "DEZZY"},
573 }, io.ErrUnexpectedEOF},
574
575
576 {"helloworld", [][]string{
577 {"NBSW", "Y3DP", "O5XX", "E3DE"},
578 {"NBSWY3DPO5XXE3DE"},
579 {"NBS", "WY3", "DPO", "5XX", "E3D", "E"},
580 {"NBSWY3DPO5XXE3", "DE"},
581 }, nil},
582
583
584 {"fooba", [][]string{
585 {"MZXW6YTBZZ"},
586 {"MZXW6YTBZ", "Z"},
587 {"MZXW6YTB", "ZZ"},
588 {"MZXW6YT", "BZZ"},
589 {"MZXW6Y", "TBZZ"},
590 {"MZXW6Y", "TB", "ZZ"},
591 {"MZXW6", "YTBZZ"},
592 {"MZXW6", "YTB", "ZZ"},
593 {"MZXW6", "YT", "BZZ"},
594 }, io.ErrUnexpectedEOF},
595
596
597 {"fooba", [][]string{
598 {"MZXW6YTB"},
599 {"MZXW6YT", "B"},
600 {"MZXW6Y", "TB"},
601 {"MZXW6", "YTB"},
602 {"MZXW6", "YT", "B"},
603 {"MZXW", "6YTB"},
604 {"MZXW", "6Y", "TB"},
605 }, nil},
606 }
607
608 for _, testcase := range testcases {
609 for _, chunks := range testcase.chunkCombinations {
610 pr, pw := io.Pipe()
611
612
613 go func() {
614 for _, chunk := range chunks {
615 pw.Write([]byte(chunk))
616 }
617 pw.Close()
618 }()
619
620 decoder := NewDecoder(StdEncoding, pr)
621 _, err := io.ReadAll(decoder)
622
623 if err != testcase.expected {
624 t.Errorf("Expected %v, got %v; case %s %+v", testcase.expected, err, testcase.prefix, chunks)
625 }
626 }
627 }
628 }
629
630 func TestEncodedDecodedLen(t *testing.T) {
631 type test struct {
632 in int
633 wantEnc int
634 wantDec int
635 }
636 data := bytes.Repeat([]byte("x"), 100)
637 for _, test := range []struct {
638 name string
639 enc *Encoding
640 cases []test
641 }{
642 {"StdEncoding", StdEncoding, []test{
643 {0, 0, 0},
644 {1, 8, 5},
645 {5, 8, 5},
646 {6, 16, 10},
647 {10, 16, 10},
648 }},
649 {"NoPadding", StdEncoding.WithPadding(NoPadding), []test{
650 {0, 0, 0},
651 {1, 2, 1},
652 {2, 4, 2},
653 {5, 8, 5},
654 {6, 10, 6},
655 {7, 12, 7},
656 {10, 16, 10},
657 {11, 18, 11},
658 }},
659 } {
660 t.Run(test.name, func(t *testing.T) {
661 for _, tc := range test.cases {
662 encLen := test.enc.EncodedLen(tc.in)
663 decLen := test.enc.DecodedLen(encLen)
664 enc := test.enc.EncodeToString(data[:tc.in])
665 if len(enc) != encLen {
666 t.Fatalf("EncodedLen(%d) = %d but encoded to %q (%d)", tc.in, encLen, enc, len(enc))
667 }
668 if encLen != tc.wantEnc {
669 t.Fatalf("EncodedLen(%d) = %d; want %d", tc.in, encLen, tc.wantEnc)
670 }
671 if decLen != tc.wantDec {
672 t.Fatalf("DecodedLen(%d) = %d; want %d", encLen, decLen, tc.wantDec)
673 }
674 }
675 })
676 }
677 }
678
679 func TestWithoutPaddingClose(t *testing.T) {
680 encodings := []*Encoding{
681 StdEncoding,
682 StdEncoding.WithPadding(NoPadding),
683 }
684
685 for _, encoding := range encodings {
686 for _, testpair := range pairs {
687
688 var buf bytes.Buffer
689 encoder := NewEncoder(encoding, &buf)
690 encoder.Write([]byte(testpair.decoded))
691 encoder.Close()
692
693 expected := testpair.encoded
694 if encoding.padChar == NoPadding {
695 expected = strings.ReplaceAll(expected, "=", "")
696 }
697
698 res := buf.String()
699
700 if res != expected {
701 t.Errorf("Expected %s got %s; padChar=%d", expected, res, encoding.padChar)
702 }
703 }
704 }
705 }
706
707 func TestDecodeReadAll(t *testing.T) {
708 encodings := []*Encoding{
709 StdEncoding,
710 StdEncoding.WithPadding(NoPadding),
711 }
712
713 for _, pair := range pairs {
714 for encIndex, encoding := range encodings {
715 encoded := pair.encoded
716 if encoding.padChar == NoPadding {
717 encoded = strings.ReplaceAll(encoded, "=", "")
718 }
719
720 decReader, err := io.ReadAll(NewDecoder(encoding, strings.NewReader(encoded)))
721 if err != nil {
722 t.Errorf("NewDecoder error: %v", err)
723 }
724
725 if pair.decoded != string(decReader) {
726 t.Errorf("Expected %s got %s; Encoding %d", pair.decoded, decReader, encIndex)
727 }
728 }
729 }
730 }
731
732 func TestDecodeSmallBuffer(t *testing.T) {
733 encodings := []*Encoding{
734 StdEncoding,
735 StdEncoding.WithPadding(NoPadding),
736 }
737
738 for bufferSize := 1; bufferSize < 200; bufferSize++ {
739 for _, pair := range pairs {
740 for encIndex, encoding := range encodings {
741 encoded := pair.encoded
742 if encoding.padChar == NoPadding {
743 encoded = strings.ReplaceAll(encoded, "=", "")
744 }
745
746 decoder := NewDecoder(encoding, strings.NewReader(encoded))
747
748 var allRead []byte
749
750 for {
751 buf := make([]byte, bufferSize)
752 n, err := decoder.Read(buf)
753 allRead = append(allRead, buf[0:n]...)
754 if err == io.EOF {
755 break
756 }
757 if err != nil {
758 t.Error(err)
759 }
760 }
761
762 if pair.decoded != string(allRead) {
763 t.Errorf("Expected %s got %s; Encoding %d; bufferSize %d", pair.decoded, allRead, encIndex, bufferSize)
764 }
765 }
766 }
767 }
768 }
769
View as plain text