github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/encoding/base32/base32_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 base32
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"io/ioutil"
    11  	"strings"
    12  	"testing"
    13  )
    14  
    15  type testpair struct {
    16  	decoded, encoded string
    17  }
    18  
    19  var pairs = []testpair{
    20  	// RFC 4648 examples
    21  	{"", ""},
    22  	{"f", "MY======"},
    23  	{"fo", "MZXQ===="},
    24  	{"foo", "MZXW6==="},
    25  	{"foob", "MZXW6YQ="},
    26  	{"fooba", "MZXW6YTB"},
    27  	{"foobar", "MZXW6YTBOI======"},
    28  
    29  	// Wikipedia examples, converted to base32
    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 ...interface{}) bool {
    46  	if args[len(args)-2] != args[len(args)-1] {
    47  		t.Errorf(msg, args...)
    48  		return false
    49  	}
    50  	return true
    51  }
    52  
    53  func TestEncode(t *testing.T) {
    54  	for _, p := range pairs {
    55  		got := StdEncoding.EncodeToString([]byte(p.decoded))
    56  		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
    57  	}
    58  }
    59  
    60  func TestEncoder(t *testing.T) {
    61  	for _, p := range pairs {
    62  		bb := &bytes.Buffer{}
    63  		encoder := NewEncoder(StdEncoding, bb)
    64  		encoder.Write([]byte(p.decoded))
    65  		encoder.Close()
    66  		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
    67  	}
    68  }
    69  
    70  func TestEncoderBuffering(t *testing.T) {
    71  	input := []byte(bigtest.decoded)
    72  	for bs := 1; bs <= 12; bs++ {
    73  		bb := &bytes.Buffer{}
    74  		encoder := NewEncoder(StdEncoding, bb)
    75  		for pos := 0; pos < len(input); pos += bs {
    76  			end := pos + bs
    77  			if end > len(input) {
    78  				end = len(input)
    79  			}
    80  			n, err := encoder.Write(input[pos:end])
    81  			testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
    82  			testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
    83  		}
    84  		err := encoder.Close()
    85  		testEqual(t, "Close gave error %v, want %v", err, error(nil))
    86  		testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
    87  	}
    88  }
    89  
    90  func TestDecode(t *testing.T) {
    91  	for _, p := range pairs {
    92  		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
    93  		count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
    94  		testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
    95  		testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
    96  		if len(p.encoded) > 0 {
    97  			testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
    98  		}
    99  		testEqual(t, "Decode(%q) = %q, want %q", p.encoded,
   100  			string(dbuf[0:count]),
   101  			p.decoded)
   102  
   103  		dbuf, err = StdEncoding.DecodeString(p.encoded)
   104  		testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
   105  		testEqual(t, "DecodeString(%q) = %q, want %q", p.encoded, string(dbuf), p.decoded)
   106  	}
   107  }
   108  
   109  func TestDecoder(t *testing.T) {
   110  	for _, p := range pairs {
   111  		decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
   112  		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
   113  		count, err := decoder.Read(dbuf)
   114  		if err != nil && err != io.EOF {
   115  			t.Fatal("Read failed", err)
   116  		}
   117  		testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
   118  		testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
   119  		if err != io.EOF {
   120  			count, err = decoder.Read(dbuf)
   121  		}
   122  		testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
   123  	}
   124  }
   125  
   126  func TestDecoderBuffering(t *testing.T) {
   127  	for bs := 1; bs <= 12; bs++ {
   128  		decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
   129  		buf := make([]byte, len(bigtest.decoded)+12)
   130  		var total int
   131  		for total = 0; total < len(bigtest.decoded); {
   132  			n, err := decoder.Read(buf[total : total+bs])
   133  			testEqual(t, "Read from %q at pos %d = %d, %v, want _, %v", bigtest.encoded, total, n, err, error(nil))
   134  			total += n
   135  		}
   136  		testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
   137  	}
   138  }
   139  
   140  func TestDecodeCorrupt(t *testing.T) {
   141  	testCases := []struct {
   142  		input  string
   143  		offset int // -1 means no corruption.
   144  	}{
   145  		{"", -1},
   146  		{"!!!!", 0},
   147  		{"x===", 0},
   148  		{"AA=A====", 2},
   149  		{"AAA=AAAA", 3},
   150  		{"MMMMMMMMM", 8},
   151  		{"MMMMMM", 0},
   152  		{"A=", 1},
   153  		{"AA=", 3},
   154  		{"AA==", 4},
   155  		{"AA===", 5},
   156  		{"AAAA=", 5},
   157  		{"AAAA==", 6},
   158  		{"AAAAA=", 6},
   159  		{"AAAAA==", 7},
   160  		{"A=======", 1},
   161  		{"AA======", -1},
   162  		{"AAA=====", 3},
   163  		{"AAAA====", -1},
   164  		{"AAAAA===", -1},
   165  		{"AAAAAA==", 6},
   166  		{"AAAAAAA=", -1},
   167  		{"AAAAAAAA", -1},
   168  	}
   169  	for _, tc := range testCases {
   170  		dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
   171  		_, err := StdEncoding.Decode(dbuf, []byte(tc.input))
   172  		if tc.offset == -1 {
   173  			if err != nil {
   174  				t.Error("Decoder wrongly detected corruption in", tc.input)
   175  			}
   176  			continue
   177  		}
   178  		switch err := err.(type) {
   179  		case CorruptInputError:
   180  			testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
   181  		default:
   182  			t.Error("Decoder failed to detect corruption in", tc)
   183  		}
   184  	}
   185  }
   186  
   187  func TestBig(t *testing.T) {
   188  	n := 3*1000 + 1
   189  	raw := make([]byte, n)
   190  	const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
   191  	for i := 0; i < n; i++ {
   192  		raw[i] = alpha[i%len(alpha)]
   193  	}
   194  	encoded := new(bytes.Buffer)
   195  	w := NewEncoder(StdEncoding, encoded)
   196  	nn, err := w.Write(raw)
   197  	if nn != n || err != nil {
   198  		t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
   199  	}
   200  	err = w.Close()
   201  	if err != nil {
   202  		t.Fatalf("Encoder.Close() = %v want nil", err)
   203  	}
   204  	decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded))
   205  	if err != nil {
   206  		t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err)
   207  	}
   208  
   209  	if !bytes.Equal(raw, decoded) {
   210  		var i int
   211  		for i = 0; i < len(decoded) && i < len(raw); i++ {
   212  			if decoded[i] != raw[i] {
   213  				break
   214  			}
   215  		}
   216  		t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
   217  	}
   218  }
   219  
   220  func testStringEncoding(t *testing.T, expected string, examples []string) {
   221  	for _, e := range examples {
   222  		buf, err := StdEncoding.DecodeString(e)
   223  		if err != nil {
   224  			t.Errorf("Decode(%q) failed: %v", e, err)
   225  			continue
   226  		}
   227  		if s := string(buf); s != expected {
   228  			t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
   229  		}
   230  	}
   231  }
   232  
   233  func TestNewLineCharacters(t *testing.T) {
   234  	// Each of these should decode to the string "sure", without errors.
   235  	examples := []string{
   236  		"ON2XEZI=",
   237  		"ON2XEZI=\r",
   238  		"ON2XEZI=\n",
   239  		"ON2XEZI=\r\n",
   240  		"ON2XEZ\r\nI=",
   241  		"ON2X\rEZ\nI=",
   242  		"ON2X\nEZ\rI=",
   243  		"ON2XEZ\nI=",
   244  		"ON2XEZI\n=",
   245  	}
   246  	testStringEncoding(t, "sure", examples)
   247  
   248  	// Each of these should decode to the string "foobar", without errors.
   249  	examples = []string{
   250  		"MZXW6YTBOI======",
   251  		"MZXW6YTBOI=\r\n=====",
   252  	}
   253  	testStringEncoding(t, "foobar", examples)
   254  }
   255  
   256  func TestDecoderIssue4779(t *testing.T) {
   257  	encoded := `JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4
   258  RAMFSGS4DJONUWG2LOM4QGK3DJOQWCA43FMQQGI3YKMVUXK43NN5SCA5DFNVYG64RANFXGG2LENFSH
   259  K3TUEB2XIIDMMFRG64TFEBSXIIDEN5WG64TFEBWWCZ3OMEQGC3DJOF2WCLRAKV2CAZLONFWQUYLEEB
   260  WWS3TJNUQHMZLONFQW2LBAOF2WS4ZANZXXG5DSOVSCAZLYMVZGG2LUMF2GS33OEB2WY3DBNVRW6IDM
   261  MFRG64TJOMQG42LTNEQHK5AKMFWGS4LVNFYCAZLYEBSWCIDDN5WW233EN4QGG33OONSXC5LBOQXCAR
   262  DVNFZSAYLVORSSA2LSOVZGKIDEN5WG64RANFXAU4TFOBZGK2DFNZSGK4TJOQQGS3RAOZXWY5LQORQX
   263  IZJAOZSWY2LUEBSXG43FEBRWS3DMOVWSAZDPNRXXEZJAMV2SAZTVM5UWC5BANZ2WY3DBBJYGC4TJMF
   264  2HK4ROEBCXQY3FOB2GK5LSEBZWS3TUEBXWGY3BMVRWC5BAMN2XA2LEMF2GC5BANZXW4IDQOJXWSZDF
   265  NZ2CYIDTOVXHIIDJNYFGG5LMOBQSA4LVNEQG6ZTGNFRWSYJAMRSXGZLSOVXHIIDNN5WGY2LUEBQW42
   266  LNEBUWIIDFON2CA3DBMJXXE5LNFY==
   267  ====`
   268  	encodedShort := strings.Replace(encoded, "\n", "", -1)
   269  
   270  	dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
   271  	res1, err := ioutil.ReadAll(dec)
   272  	if err != nil {
   273  		t.Errorf("ReadAll failed: %v", err)
   274  	}
   275  
   276  	dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
   277  	var res2 []byte
   278  	res2, err = ioutil.ReadAll(dec)
   279  	if err != nil {
   280  		t.Errorf("ReadAll failed: %v", err)
   281  	}
   282  
   283  	if !bytes.Equal(res1, res2) {
   284  		t.Error("Decoded results not equal")
   285  	}
   286  }
   287  
   288  func BenchmarkEncodeToString(b *testing.B) {
   289  	data := make([]byte, 8192)
   290  	b.SetBytes(int64(len(data)))
   291  	for i := 0; i < b.N; i++ {
   292  		StdEncoding.EncodeToString(data)
   293  	}
   294  }
   295  
   296  func BenchmarkDecodeString(b *testing.B) {
   297  	data := StdEncoding.EncodeToString(make([]byte, 8192))
   298  	b.SetBytes(int64(len(data)))
   299  	for i := 0; i < b.N; i++ {
   300  		StdEncoding.DecodeString(data)
   301  	}
   302  }