...

Source file src/encoding/base64/base64_test.go

Documentation: encoding/base64

		 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  	"fmt"
		11  	"io"
		12  	"reflect"
		13  	"runtime/debug"
		14  	"strings"
		15  	"testing"
		16  	"time"
		17  )
		18  
		19  type testpair struct {
		20  	decoded, encoded string
		21  }
		22  
		23  var pairs = []testpair{
		24  	// RFC 3548 examples
		25  	{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"},
		26  	{"\x14\xfb\x9c\x03\xd9", "FPucA9k="},
		27  	{"\x14\xfb\x9c\x03", "FPucAw=="},
		28  
		29  	// RFC 4648 examples
		30  	{"", ""},
		31  	{"f", "Zg=="},
		32  	{"fo", "Zm8="},
		33  	{"foo", "Zm9v"},
		34  	{"foob", "Zm9vYg=="},
		35  	{"fooba", "Zm9vYmE="},
		36  	{"foobar", "Zm9vYmFy"},
		37  
		38  	// Wikipedia examples
		39  	{"sure.", "c3VyZS4="},
		40  	{"sure", "c3VyZQ=="},
		41  	{"sur", "c3Vy"},
		42  	{"su", "c3U="},
		43  	{"leasure.", "bGVhc3VyZS4="},
		44  	{"easure.", "ZWFzdXJlLg=="},
		45  	{"asure.", "YXN1cmUu"},
		46  	{"sure.", "c3VyZS4="},
		47  }
		48  
		49  // Do nothing to a reference base64 string (leave in standard format)
		50  func stdRef(ref string) string {
		51  	return ref
		52  }
		53  
		54  // Convert a reference string to URL-encoding
		55  func urlRef(ref string) string {
		56  	ref = strings.ReplaceAll(ref, "+", "-")
		57  	ref = strings.ReplaceAll(ref, "/", "_")
		58  	return ref
		59  }
		60  
		61  // Convert a reference string to raw, unpadded format
		62  func rawRef(ref string) string {
		63  	return strings.TrimRight(ref, "=")
		64  }
		65  
		66  // Both URL and unpadding conversions
		67  func rawURLRef(ref string) string {
		68  	return rawRef(urlRef(ref))
		69  }
		70  
		71  // A nonstandard encoding with a funny padding character, for testing
		72  var funnyEncoding = NewEncoding(encodeStd).WithPadding(rune('@'))
		73  
		74  func funnyRef(ref string) string {
		75  	return strings.ReplaceAll(ref, "=", "@")
		76  }
		77  
		78  type encodingTest struct {
		79  	enc	*Encoding					 // Encoding to test
		80  	conv func(string) string // Reference string converter
		81  }
		82  
		83  var encodingTests = []encodingTest{
		84  	{StdEncoding, stdRef},
		85  	{URLEncoding, urlRef},
		86  	{RawStdEncoding, rawRef},
		87  	{RawURLEncoding, rawURLRef},
		88  	{funnyEncoding, funnyRef},
		89  	{StdEncoding.Strict(), stdRef},
		90  	{URLEncoding.Strict(), urlRef},
		91  	{RawStdEncoding.Strict(), rawRef},
		92  	{RawURLEncoding.Strict(), rawURLRef},
		93  	{funnyEncoding.Strict(), funnyRef},
		94  }
		95  
		96  var bigtest = testpair{
		97  	"Twas brillig, and the slithy toves",
		98  	"VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==",
		99  }
	 100  
	 101  func testEqual(t *testing.T, msg string, args ...interface{}) bool {
	 102  	t.Helper()
	 103  	if args[len(args)-2] != args[len(args)-1] {
	 104  		t.Errorf(msg, args...)
	 105  		return false
	 106  	}
	 107  	return true
	 108  }
	 109  
	 110  func TestEncode(t *testing.T) {
	 111  	for _, p := range pairs {
	 112  		for _, tt := range encodingTests {
	 113  			got := tt.enc.EncodeToString([]byte(p.decoded))
	 114  			testEqual(t, "Encode(%q) = %q, want %q", p.decoded,
	 115  				got, tt.conv(p.encoded))
	 116  		}
	 117  	}
	 118  }
	 119  
	 120  func TestEncoder(t *testing.T) {
	 121  	for _, p := range pairs {
	 122  		bb := &bytes.Buffer{}
	 123  		encoder := NewEncoder(StdEncoding, bb)
	 124  		encoder.Write([]byte(p.decoded))
	 125  		encoder.Close()
	 126  		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
	 127  	}
	 128  }
	 129  
	 130  func TestEncoderBuffering(t *testing.T) {
	 131  	input := []byte(bigtest.decoded)
	 132  	for bs := 1; bs <= 12; bs++ {
	 133  		bb := &bytes.Buffer{}
	 134  		encoder := NewEncoder(StdEncoding, bb)
	 135  		for pos := 0; pos < len(input); pos += bs {
	 136  			end := pos + bs
	 137  			if end > len(input) {
	 138  				end = len(input)
	 139  			}
	 140  			n, err := encoder.Write(input[pos:end])
	 141  			testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
	 142  			testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
	 143  		}
	 144  		err := encoder.Close()
	 145  		testEqual(t, "Close gave error %v, want %v", err, error(nil))
	 146  		testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
	 147  	}
	 148  }
	 149  
	 150  func TestDecode(t *testing.T) {
	 151  	for _, p := range pairs {
	 152  		for _, tt := range encodingTests {
	 153  			encoded := tt.conv(p.encoded)
	 154  			dbuf := make([]byte, tt.enc.DecodedLen(len(encoded)))
	 155  			count, err := tt.enc.Decode(dbuf, []byte(encoded))
	 156  			testEqual(t, "Decode(%q) = error %v, want %v", encoded, err, error(nil))
	 157  			testEqual(t, "Decode(%q) = length %v, want %v", encoded, count, len(p.decoded))
	 158  			testEqual(t, "Decode(%q) = %q, want %q", encoded, string(dbuf[0:count]), p.decoded)
	 159  
	 160  			dbuf, err = tt.enc.DecodeString(encoded)
	 161  			testEqual(t, "DecodeString(%q) = error %v, want %v", encoded, err, error(nil))
	 162  			testEqual(t, "DecodeString(%q) = %q, want %q", encoded, string(dbuf), p.decoded)
	 163  		}
	 164  	}
	 165  }
	 166  
	 167  func TestDecoder(t *testing.T) {
	 168  	for _, p := range pairs {
	 169  		decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
	 170  		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
	 171  		count, err := decoder.Read(dbuf)
	 172  		if err != nil && err != io.EOF {
	 173  			t.Fatal("Read failed", err)
	 174  		}
	 175  		testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
	 176  		testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
	 177  		if err != io.EOF {
	 178  			_, err = decoder.Read(dbuf)
	 179  		}
	 180  		testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
	 181  	}
	 182  }
	 183  
	 184  func TestDecoderBuffering(t *testing.T) {
	 185  	for bs := 1; bs <= 12; bs++ {
	 186  		decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
	 187  		buf := make([]byte, len(bigtest.decoded)+12)
	 188  		var total int
	 189  		var n int
	 190  		var err error
	 191  		for total = 0; total < len(bigtest.decoded) && err == nil; {
	 192  			n, err = decoder.Read(buf[total : total+bs])
	 193  			total += n
	 194  		}
	 195  		if err != nil && err != io.EOF {
	 196  			t.Errorf("Read from %q at pos %d = %d, unexpected error %v", bigtest.encoded, total, n, err)
	 197  		}
	 198  		testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
	 199  	}
	 200  }
	 201  
	 202  func TestDecodeCorrupt(t *testing.T) {
	 203  	testCases := []struct {
	 204  		input	string
	 205  		offset int // -1 means no corruption.
	 206  	}{
	 207  		{"", -1},
	 208  		{"\n", -1},
	 209  		{"AAA=\n", -1},
	 210  		{"AAAA\n", -1},
	 211  		{"!!!!", 0},
	 212  		{"====", 0},
	 213  		{"x===", 1},
	 214  		{"=AAA", 0},
	 215  		{"A=AA", 1},
	 216  		{"AA=A", 2},
	 217  		{"AA==A", 4},
	 218  		{"AAA=AAAA", 4},
	 219  		{"AAAAA", 4},
	 220  		{"AAAAAA", 4},
	 221  		{"A=", 1},
	 222  		{"A==", 1},
	 223  		{"AA=", 3},
	 224  		{"AA==", -1},
	 225  		{"AAA=", -1},
	 226  		{"AAAA", -1},
	 227  		{"AAAAAA=", 7},
	 228  		{"YWJjZA=====", 8},
	 229  		{"A!\n", 1},
	 230  		{"A=\n", 1},
	 231  	}
	 232  	for _, tc := range testCases {
	 233  		dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
	 234  		_, err := StdEncoding.Decode(dbuf, []byte(tc.input))
	 235  		if tc.offset == -1 {
	 236  			if err != nil {
	 237  				t.Error("Decoder wrongly detected corruption in", tc.input)
	 238  			}
	 239  			continue
	 240  		}
	 241  		switch err := err.(type) {
	 242  		case CorruptInputError:
	 243  			testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
	 244  		default:
	 245  			t.Error("Decoder failed to detect corruption in", tc)
	 246  		}
	 247  	}
	 248  }
	 249  
	 250  func TestDecodeBounds(t *testing.T) {
	 251  	var buf [32]byte
	 252  	s := StdEncoding.EncodeToString(buf[:])
	 253  	defer func() {
	 254  		if err := recover(); err != nil {
	 255  			t.Fatalf("Decode panicked unexpectedly: %v\n%s", err, debug.Stack())
	 256  		}
	 257  	}()
	 258  	n, err := StdEncoding.Decode(buf[:], []byte(s))
	 259  	if n != len(buf) || err != nil {
	 260  		t.Fatalf("StdEncoding.Decode = %d, %v, want %d, nil", n, err, len(buf))
	 261  	}
	 262  }
	 263  
	 264  func TestEncodedLen(t *testing.T) {
	 265  	for _, tt := range []struct {
	 266  		enc	*Encoding
	 267  		n		int
	 268  		want int
	 269  	}{
	 270  		{RawStdEncoding, 0, 0},
	 271  		{RawStdEncoding, 1, 2},
	 272  		{RawStdEncoding, 2, 3},
	 273  		{RawStdEncoding, 3, 4},
	 274  		{RawStdEncoding, 7, 10},
	 275  		{StdEncoding, 0, 0},
	 276  		{StdEncoding, 1, 4},
	 277  		{StdEncoding, 2, 4},
	 278  		{StdEncoding, 3, 4},
	 279  		{StdEncoding, 4, 8},
	 280  		{StdEncoding, 7, 12},
	 281  	} {
	 282  		if got := tt.enc.EncodedLen(tt.n); got != tt.want {
	 283  			t.Errorf("EncodedLen(%d): got %d, want %d", tt.n, got, tt.want)
	 284  		}
	 285  	}
	 286  }
	 287  
	 288  func TestDecodedLen(t *testing.T) {
	 289  	for _, tt := range []struct {
	 290  		enc	*Encoding
	 291  		n		int
	 292  		want int
	 293  	}{
	 294  		{RawStdEncoding, 0, 0},
	 295  		{RawStdEncoding, 2, 1},
	 296  		{RawStdEncoding, 3, 2},
	 297  		{RawStdEncoding, 4, 3},
	 298  		{RawStdEncoding, 10, 7},
	 299  		{StdEncoding, 0, 0},
	 300  		{StdEncoding, 4, 3},
	 301  		{StdEncoding, 8, 6},
	 302  	} {
	 303  		if got := tt.enc.DecodedLen(tt.n); got != tt.want {
	 304  			t.Errorf("DecodedLen(%d): got %d, want %d", tt.n, got, tt.want)
	 305  		}
	 306  	}
	 307  }
	 308  
	 309  func TestBig(t *testing.T) {
	 310  	n := 3*1000 + 1
	 311  	raw := make([]byte, n)
	 312  	const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	 313  	for i := 0; i < n; i++ {
	 314  		raw[i] = alpha[i%len(alpha)]
	 315  	}
	 316  	encoded := new(bytes.Buffer)
	 317  	w := NewEncoder(StdEncoding, encoded)
	 318  	nn, err := w.Write(raw)
	 319  	if nn != n || err != nil {
	 320  		t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
	 321  	}
	 322  	err = w.Close()
	 323  	if err != nil {
	 324  		t.Fatalf("Encoder.Close() = %v want nil", err)
	 325  	}
	 326  	decoded, err := io.ReadAll(NewDecoder(StdEncoding, encoded))
	 327  	if err != nil {
	 328  		t.Fatalf("io.ReadAll(NewDecoder(...)): %v", err)
	 329  	}
	 330  
	 331  	if !bytes.Equal(raw, decoded) {
	 332  		var i int
	 333  		for i = 0; i < len(decoded) && i < len(raw); i++ {
	 334  			if decoded[i] != raw[i] {
	 335  				break
	 336  			}
	 337  		}
	 338  		t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
	 339  	}
	 340  }
	 341  
	 342  func TestNewLineCharacters(t *testing.T) {
	 343  	// Each of these should decode to the string "sure", without errors.
	 344  	const expected = "sure"
	 345  	examples := []string{
	 346  		"c3VyZQ==",
	 347  		"c3VyZQ==\r",
	 348  		"c3VyZQ==\n",
	 349  		"c3VyZQ==\r\n",
	 350  		"c3VyZ\r\nQ==",
	 351  		"c3V\ryZ\nQ==",
	 352  		"c3V\nyZ\rQ==",
	 353  		"c3VyZ\nQ==",
	 354  		"c3VyZQ\n==",
	 355  		"c3VyZQ=\n=",
	 356  		"c3VyZQ=\r\n\r\n=",
	 357  	}
	 358  	for _, e := range examples {
	 359  		buf, err := StdEncoding.DecodeString(e)
	 360  		if err != nil {
	 361  			t.Errorf("Decode(%q) failed: %v", e, err)
	 362  			continue
	 363  		}
	 364  		if s := string(buf); s != expected {
	 365  			t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
	 366  		}
	 367  	}
	 368  }
	 369  
	 370  type nextRead struct {
	 371  	n	 int	 // bytes to return
	 372  	err error // error to return
	 373  }
	 374  
	 375  // faultInjectReader returns data from source, rate-limited
	 376  // and with the errors as written to nextc.
	 377  type faultInjectReader struct {
	 378  	source string
	 379  	nextc	<-chan nextRead
	 380  }
	 381  
	 382  func (r *faultInjectReader) Read(p []byte) (int, error) {
	 383  	nr := <-r.nextc
	 384  	if len(p) > nr.n {
	 385  		p = p[:nr.n]
	 386  	}
	 387  	n := copy(p, r.source)
	 388  	r.source = r.source[n:]
	 389  	return n, nr.err
	 390  }
	 391  
	 392  // tests that we don't ignore errors from our underlying reader
	 393  func TestDecoderIssue3577(t *testing.T) {
	 394  	next := make(chan nextRead, 10)
	 395  	wantErr := errors.New("my error")
	 396  	next <- nextRead{5, nil}
	 397  	next <- nextRead{10, wantErr}
	 398  	next <- nextRead{0, wantErr}
	 399  	d := NewDecoder(StdEncoding, &faultInjectReader{
	 400  		source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig...
	 401  		nextc:	next,
	 402  	})
	 403  	errc := make(chan error, 1)
	 404  	go func() {
	 405  		_, err := io.ReadAll(d)
	 406  		errc <- err
	 407  	}()
	 408  	select {
	 409  	case err := <-errc:
	 410  		if err != wantErr {
	 411  			t.Errorf("got error %v; want %v", err, wantErr)
	 412  		}
	 413  	case <-time.After(5 * time.Second):
	 414  		t.Errorf("timeout; Decoder blocked without returning an error")
	 415  	}
	 416  }
	 417  
	 418  func TestDecoderIssue4779(t *testing.T) {
	 419  	encoded := `CP/EAT8AAAEF
	 420  AQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAAB
	 421  BAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHx
	 422  Y3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm
	 423  9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS
	 424  0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0
	 425  pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkJ+Tj
	 426  1kiy1jCJJDnAcCTykpKkuQ6p/jN6FgmxlNduXawwAzaGH+V6jn/R/wCt71zdn+N/qL3kVYFNYB4N
	 427  ji6PDVjWpKp9TSXnvTf8bFNjg3qOEa2n6VlLpj/rT/pf567DpX1i6L1hs9Py67X8mqdtg/rUWbbf
	 428  +gkp0kkkklKSSSSUpJJJJT//0PVUkkklKVLq3WMDpGI7KzrNjADtYNXvI/Mqr/Pd/q9W3vaxjnvM
	 429  NaCXE9gNSvGPrf8AWS3qmba5jjsJhoB0DAf0NDf6sevf+/lf8Hj0JJATfWT6/dV6oXU1uOLQeKKn
	 430  EQP+Hubtfe/+R7Mf/g7f5xcocp++Z11JMCJPgFBxOg7/AOuqDx8I/ikpkXkmSdU8mJIJA/O8EMAy
	 431  j+mSARB/17pKVXYWHXjsj7yIex0PadzXMO1zT5KHoNA3HT8ietoGhgjsfA+CSnvvqh/jJtqsrwOv
	 432  2b6NGNzXfTYexzJ+nU7/ALkf4P8Awv6P9KvTQQ4AgyDqCF85Pho3CTB7eHwXoH+LT65uZbX9X+o2
	 433  bqbPb06551Y4
	 434  `
	 435  	encodedShort := strings.ReplaceAll(encoded, "\n", "")
	 436  
	 437  	dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
	 438  	res1, err := io.ReadAll(dec)
	 439  	if err != nil {
	 440  		t.Errorf("ReadAll failed: %v", err)
	 441  	}
	 442  
	 443  	dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
	 444  	var res2 []byte
	 445  	res2, err = io.ReadAll(dec)
	 446  	if err != nil {
	 447  		t.Errorf("ReadAll failed: %v", err)
	 448  	}
	 449  
	 450  	if !bytes.Equal(res1, res2) {
	 451  		t.Error("Decoded results not equal")
	 452  	}
	 453  }
	 454  
	 455  func TestDecoderIssue7733(t *testing.T) {
	 456  	s, err := StdEncoding.DecodeString("YWJjZA=====")
	 457  	want := CorruptInputError(8)
	 458  	if !reflect.DeepEqual(want, err) {
	 459  		t.Errorf("Error = %v; want CorruptInputError(8)", err)
	 460  	}
	 461  	if string(s) != "abcd" {
	 462  		t.Errorf("DecodeString = %q; want abcd", s)
	 463  	}
	 464  }
	 465  
	 466  func TestDecoderIssue15656(t *testing.T) {
	 467  	_, err := StdEncoding.Strict().DecodeString("WvLTlMrX9NpYDQlEIFlnDB==")
	 468  	want := CorruptInputError(22)
	 469  	if !reflect.DeepEqual(want, err) {
	 470  		t.Errorf("Error = %v; want CorruptInputError(22)", err)
	 471  	}
	 472  	_, err = StdEncoding.Strict().DecodeString("WvLTlMrX9NpYDQlEIFlnDA==")
	 473  	if err != nil {
	 474  		t.Errorf("Error = %v; want nil", err)
	 475  	}
	 476  	_, err = StdEncoding.DecodeString("WvLTlMrX9NpYDQlEIFlnDB==")
	 477  	if err != nil {
	 478  		t.Errorf("Error = %v; want nil", err)
	 479  	}
	 480  }
	 481  
	 482  func BenchmarkEncodeToString(b *testing.B) {
	 483  	data := make([]byte, 8192)
	 484  	b.SetBytes(int64(len(data)))
	 485  	for i := 0; i < b.N; i++ {
	 486  		StdEncoding.EncodeToString(data)
	 487  	}
	 488  }
	 489  
	 490  func BenchmarkDecodeString(b *testing.B) {
	 491  	sizes := []int{2, 4, 8, 64, 8192}
	 492  	benchFunc := func(b *testing.B, benchSize int) {
	 493  		data := StdEncoding.EncodeToString(make([]byte, benchSize))
	 494  		b.SetBytes(int64(len(data)))
	 495  		b.ResetTimer()
	 496  		for i := 0; i < b.N; i++ {
	 497  			StdEncoding.DecodeString(data)
	 498  		}
	 499  	}
	 500  	for _, size := range sizes {
	 501  		b.Run(fmt.Sprintf("%d", size), func(b *testing.B) {
	 502  			benchFunc(b, size)
	 503  		})
	 504  	}
	 505  }
	 506  
	 507  func TestDecoderRaw(t *testing.T) {
	 508  	source := "AAAAAA"
	 509  	want := []byte{0, 0, 0, 0}
	 510  
	 511  	// Direct.
	 512  	dec1, err := RawURLEncoding.DecodeString(source)
	 513  	if err != nil || !bytes.Equal(dec1, want) {
	 514  		t.Errorf("RawURLEncoding.DecodeString(%q) = %x, %v, want %x, nil", source, dec1, err, want)
	 515  	}
	 516  
	 517  	// Through reader. Used to fail.
	 518  	r := NewDecoder(RawURLEncoding, bytes.NewReader([]byte(source)))
	 519  	dec2, err := io.ReadAll(io.LimitReader(r, 100))
	 520  	if err != nil || !bytes.Equal(dec2, want) {
	 521  		t.Errorf("reading NewDecoder(RawURLEncoding, %q) = %x, %v, want %x, nil", source, dec2, err, want)
	 522  	}
	 523  
	 524  	// Should work with padding.
	 525  	r = NewDecoder(URLEncoding, bytes.NewReader([]byte(source+"==")))
	 526  	dec3, err := io.ReadAll(r)
	 527  	if err != nil || !bytes.Equal(dec3, want) {
	 528  		t.Errorf("reading NewDecoder(URLEncoding, %q) = %x, %v, want %x, nil", source+"==", dec3, err, want)
	 529  	}
	 530  }
	 531  

View as plain text