github.com/segmentio/encoding@v0.4.0/json/json_test.go (about) 1 package json 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "encoding" 7 "encoding/json" 8 "errors" 9 "flag" 10 "fmt" 11 "io" 12 "math" 13 "math/big" 14 "os" 15 "path/filepath" 16 "reflect" 17 "runtime" 18 "strconv" 19 "strings" 20 "testing" 21 "time" 22 ) 23 24 // The encoding/json package does not export the msg field of json.SyntaxError, 25 // so we use this replacement type in tests. 26 type testSyntaxError struct { 27 msg string 28 Offset int64 29 } 30 31 func (e *testSyntaxError) Error() string { return e.msg } 32 33 var ( 34 marshal func([]byte, interface{}) ([]byte, error) 35 unmarshal func([]byte, interface{}) error 36 escapeHTML bool 37 ) 38 39 func TestMain(m *testing.M) { 40 var pkg string 41 flag.StringVar(&pkg, "package", ".", "The name of the package to test (encoding/json, or default to this package)") 42 flag.BoolVar(&escapeHTML, "escapehtml", false, "Whether to enable HTML escaping or not") 43 flag.Parse() 44 45 switch pkg { 46 case "encoding/json": 47 buf := &buffer{} 48 enc := json.NewEncoder(buf) 49 enc.SetEscapeHTML(escapeHTML) 50 51 marshal = func(b []byte, v interface{}) ([]byte, error) { 52 buf.data = b 53 err := enc.Encode(v) 54 return buf.data, err 55 } 56 57 unmarshal = json.Unmarshal 58 59 default: 60 flags := AppendFlags(0) 61 if escapeHTML { 62 flags |= EscapeHTML 63 } 64 65 marshal = func(b []byte, v interface{}) ([]byte, error) { 66 return Append(b, v, flags) 67 } 68 69 unmarshal = func(b []byte, v interface{}) error { 70 _, err := Parse(b, v, ZeroCopy) 71 return err 72 } 73 } 74 75 os.Exit(m.Run()) 76 } 77 78 type point struct { 79 X int `json:"x"` 80 Y int `json:"y"` 81 } 82 83 type tree struct { 84 Value string 85 Left *tree 86 Right *tree 87 } 88 89 var ( 90 // bigPos128 and bigNeg128 are 1<<128 and -1<<128 91 // certainly neither is representable using a uint64/int64. 92 bigPos128 = new(big.Int).Lsh(big.NewInt(1), 128) 93 bigNeg128 = new(big.Int).Neg(bigPos128) 94 ) 95 96 var testValues = [...]interface{}{ 97 // constants 98 nil, 99 false, 100 true, 101 102 // int 103 int(0), 104 int(1), 105 int(42), 106 int(-1), 107 int(-42), 108 int8(math.MaxInt8), 109 int8(math.MinInt8), 110 int16(math.MaxInt16), 111 int16(math.MinInt16), 112 int32(math.MaxInt32), 113 int32(math.MinInt32), 114 int64(math.MaxInt64), 115 int64(math.MinInt64), 116 117 // uint 118 uint(0), 119 uint(1), 120 uintptr(0), 121 uintptr(1), 122 uint8(math.MaxUint8), 123 uint16(math.MaxUint16), 124 uint32(math.MaxUint32), 125 uint64(math.MaxUint64), 126 127 // float 128 float32(0), 129 float32(0.5), 130 float32(math.SmallestNonzeroFloat32), 131 float32(math.MaxFloat32), 132 float64(0), 133 float64(0.5), 134 float64(math.SmallestNonzeroFloat64), 135 float64(math.MaxFloat64), 136 137 bigPos128, 138 bigNeg128, 139 140 // number 141 Number("0"), 142 Number("1234567890"), 143 Number("-0.5"), 144 Number("-1e+2"), 145 146 // string 147 "", 148 "Hello World!", 149 "Hello\"World!", 150 "Hello\\World!", 151 "Hello\nWorld!", 152 "Hello\rWorld!", 153 "Hello\tWorld!", 154 "Hello\bWorld!", 155 "Hello\fWorld!", 156 "你好", 157 "<", 158 ">", 159 "&", 160 "\u001944", 161 "\u00c2e>", 162 "\u00c2V?", 163 "\u000e=8", 164 "\u001944\u00c2e>\u00c2V?\u000e=8", 165 "ir\u001bQJ\u007f\u0007y\u0015)", 166 strings.Repeat("A", 32), 167 strings.Repeat("A", 250), 168 strings.Repeat("A", 1020), 169 170 // bytes 171 []byte(""), 172 []byte("Hello World!"), 173 bytes.Repeat([]byte("A"), 250), 174 bytes.Repeat([]byte("A"), 1020), 175 176 // time 177 time.Unix(0, 0).In(time.UTC), 178 time.Unix(1, 42).In(time.UTC), 179 time.Unix(17179869184, 999999999).In(time.UTC), 180 time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), 181 182 // array 183 [...]int{}, 184 [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 185 186 // slice 187 []int{}, 188 []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 189 makeSlice(250), 190 makeSlice(1020), 191 []string{"A", "B", "C"}, 192 []interface{}{nil, true, false, 0.5, "Hello World!"}, 193 194 // map 195 makeMapStringBool(0), 196 makeMapStringBool(15), 197 makeMapStringBool(1020), 198 makeMapStringString(0), 199 makeMapStringString(15), 200 makeMapStringString(1020), 201 makeMapStringStringSlice(0), 202 makeMapStringStringSlice(15), 203 makeMapStringStringSlice(1020), 204 makeMapStringInterface(0), 205 makeMapStringInterface(15), 206 makeMapStringInterface(1020), 207 map[int]bool{1: false, 42: true}, 208 map[textValue]bool{{1, 2}: true, {3, 4}: false}, 209 map[string]*point{ 210 "A": {1, 2}, 211 "B": {3, 4}, 212 "C": {5, 6}, 213 }, 214 map[string]RawMessage{ 215 "A": RawMessage(`{}`), 216 "B": RawMessage(`null`), 217 "C": RawMessage(`42`), 218 }, 219 220 // struct 221 struct{}{}, 222 struct{ A int }{42}, 223 struct{ A, B, C int }{1, 2, 3}, 224 struct { 225 A int 226 T time.Time 227 S string 228 }{42, time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), "Hello World!"}, 229 // These types are interesting because they fit in a pointer so the compiler 230 // puts their value directly into the pointer field of the interface{} that 231 // is passed to Marshal. 232 struct{ X *int }{}, 233 struct{ X *int }{new(int)}, 234 struct{ X **int }{}, 235 // Struct types with more than one pointer, those exercise the regular 236 // pointer handling with code that dereferences the fields. 237 struct{ X, Y *int }{}, 238 struct{ X, Y *int }{new(int), new(int)}, 239 struct { 240 A string `json:"name"` 241 B string `json:"-"` 242 C string `json:",omitempty"` 243 D map[string]interface{} `json:",string"` 244 e string 245 }{A: "Luke", D: map[string]interface{}{"answer": float64(42)}}, 246 struct{ point }{point{1, 2}}, 247 tree{ 248 Value: "T", 249 Left: &tree{Value: "L"}, 250 Right: &tree{Value: "R", Left: &tree{Value: "R-L"}}, 251 }, 252 253 // pointer 254 (*string)(nil), 255 new(int), 256 257 // Marshaler/Unmarshaler 258 jsonValue{}, 259 jsonValue{1, 2}, 260 261 // encoding.TextMarshaler/encoding.TextUnmarshaler 262 textValue{}, 263 textValue{1, 2}, 264 265 // RawMessage 266 RawMessage(`{ 267 "answer": 42, 268 "hello": "world" 269 }`), 270 271 // fixtures 272 loadTestdata(filepath.Join(runtime.GOROOT(), "src/encoding/json/testdata/code.json.gz")), 273 } 274 275 var durationTestValues = []interface{}{ 276 // duration 277 time.Nanosecond, 278 time.Microsecond, 279 time.Millisecond, 280 time.Second, 281 time.Minute, 282 time.Hour, 283 284 // struct with duration 285 struct{ D1, D2 time.Duration }{time.Millisecond, time.Hour}, 286 } 287 288 func makeSlice(n int) []int { 289 s := make([]int, n) 290 for i := range s { 291 s[i] = i 292 } 293 return s 294 } 295 296 func makeMapStringBool(n int) map[string]bool { 297 m := make(map[string]bool, n) 298 for i := 0; i != n; i++ { 299 m[strconv.Itoa(i)] = true 300 } 301 return m 302 } 303 304 func makeMapStringString(n int) map[string]string { 305 m := make(map[string]string, n) 306 for i := 0; i != n; i++ { 307 m[strconv.Itoa(i)] = fmt.Sprintf("%d Hello, world!", i) 308 } 309 return m 310 } 311 312 func makeMapStringStringSlice(n int) map[string][]string { 313 m := make(map[string][]string, n) 314 for i := 0; i != n; i++ { 315 m[strconv.Itoa(i)] = []string{strconv.Itoa(i), "Hello,", "world!"} 316 } 317 return m 318 } 319 320 func makeMapStringInterface(n int) map[string]interface{} { 321 m := make(map[string]interface{}, n) 322 for i := 0; i != n; i++ { 323 m[strconv.Itoa(i)] = nil 324 } 325 return m 326 } 327 328 func testName(v interface{}) string { 329 return fmt.Sprintf("%T", v) 330 } 331 332 type codeResponse2 struct { 333 Tree *codeNode2 `json:"tree"` 334 Username string `json:"username"` 335 } 336 337 type codeNode2 struct { 338 Name string `json:"name"` 339 Kids []*codeNode `json:"kids"` 340 CLWeight float64 `json:"cl_weight"` 341 Touches int `json:"touches"` 342 MinT int64 `json:"min_t"` 343 MaxT int64 `json:"max_t"` 344 MeanT int64 `json:"mean_t"` 345 } 346 347 func loadTestdata(path string) interface{} { 348 f, err := os.Open(path) 349 if err != nil { 350 return err.Error() 351 } 352 defer f.Close() 353 354 r, err := gzip.NewReader(f) 355 if err != nil { 356 return err.Error() 357 } 358 defer r.Close() 359 360 testdata := new(codeResponse2) 361 if err := json.NewDecoder(r).Decode(testdata); err != nil { 362 return err.Error() 363 } 364 return testdata 365 } 366 367 func TestCodec(t *testing.T) { 368 for _, v1 := range testValues { 369 t.Run(testName(v1), func(t *testing.T) { 370 v2 := newValue(v1) 371 372 a, err := json.MarshalIndent(v1, "", "\t") 373 if err != nil { 374 t.Error(err) 375 return 376 } 377 a = append(a, '\n') 378 379 buf := &bytes.Buffer{} 380 enc := NewEncoder(buf) 381 enc.SetIndent("", "\t") 382 383 if err := enc.Encode(v1); err != nil { 384 t.Error(err) 385 return 386 } 387 b := buf.Bytes() 388 389 if !Valid(b) { 390 t.Error("invalid JSON representation") 391 } 392 393 if !bytes.Equal(a, b) { 394 t.Error("JSON representations mismatch") 395 t.Log("expected:", string(a)) 396 t.Log("found: ", string(b)) 397 } 398 399 dec := NewDecoder(bytes.NewBuffer(b)) 400 401 if err := dec.Decode(v2.Interface()); err != nil { 402 t.Errorf("%T: %v", err, err) 403 return 404 } 405 406 x1 := v1 407 x2 := v2.Elem().Interface() 408 409 if !reflect.DeepEqual(x1, x2) { 410 t.Error("values mismatch") 411 t.Logf("expected: %#v", x1) 412 t.Logf("found: %#v", x2) 413 } 414 415 if b, err := io.ReadAll(dec.Buffered()); err != nil { 416 t.Error(err) 417 } else if len(b) != 0 { 418 t.Errorf("leftover trailing bytes in the decoder: %q", b) 419 } 420 }) 421 } 422 } 423 424 // TestCodecDuration isolates testing of time.Duration. The stdlib un/marshals 425 // this type as integers whereas this library un/marshals formatted string 426 // values. Therefore, plugging durations into TestCodec would cause fail since 427 // it checks equality on the marshaled strings from the two libraries. 428 func TestCodecDuration(t *testing.T) { 429 for _, v1 := range durationTestValues { 430 t.Run(testName(v1), func(t *testing.T) { 431 v2 := newValue(v1) 432 433 // encode using stdlib. (will be an int) 434 std, err := json.MarshalIndent(v1, "", "\t") 435 if err != nil { 436 t.Error(err) 437 return 438 } 439 std = append(std, '\n') 440 441 // decode using our decoder. (reads int to duration) 442 dec := NewDecoder(bytes.NewBuffer([]byte(std))) 443 444 if err := dec.Decode(v2.Interface()); err != nil { 445 t.Errorf("%T: %v", err, err) 446 return 447 } 448 449 x1 := v1 450 x2 := v2.Elem().Interface() 451 452 if !reflect.DeepEqual(x1, x2) { 453 t.Error("values mismatch") 454 t.Logf("expected: %#v", x1) 455 t.Logf("found: %#v", x2) 456 } 457 458 // encoding using our encoder. (writes duration as string) 459 buf := &bytes.Buffer{} 460 enc := NewEncoder(buf) 461 enc.SetIndent("", "\t") 462 463 if err := enc.Encode(v1); err != nil { 464 t.Error(err) 465 return 466 } 467 b := buf.Bytes() 468 469 if !Valid(b) { 470 t.Error("invalid JSON representation") 471 } 472 473 if reflect.DeepEqual(std, b) { 474 t.Error("encoded durations should not match stdlib") 475 t.Logf("got: %s", b) 476 } 477 478 // decode using our decoder. (reads string to duration) 479 dec = NewDecoder(bytes.NewBuffer([]byte(std))) 480 481 if err := dec.Decode(v2.Interface()); err != nil { 482 t.Errorf("%T: %v", err, err) 483 return 484 } 485 486 x1 = v1 487 x2 = v2.Elem().Interface() 488 489 if !reflect.DeepEqual(x1, x2) { 490 t.Error("values mismatch") 491 t.Logf("expected: %#v", x1) 492 t.Logf("found: %#v", x2) 493 } 494 }) 495 } 496 } 497 498 var numericParseTests = [...]struct { 499 name string 500 input string 501 flags ParseFlags 502 want any 503 }{ 504 { 505 name: "zero_flags_default", 506 input: `0`, 507 flags: 0, 508 want: float64(0), 509 }, 510 { 511 name: "zero_flags_int_uint_bigint_number", 512 input: `0`, 513 flags: UseInt64 | UseUint64 | UseBigInt | UseNumber, 514 want: uint64(0), 515 }, 516 { 517 name: "zero_flags_int_bigint_number", 518 input: `0`, 519 flags: UseInt64 | UseBigInt | UseNumber, 520 want: int64(0), 521 }, 522 { 523 name: "zero_flags_bigint_number", 524 input: `0`, 525 flags: UseBigInt | UseNumber, 526 want: big.NewInt(0), 527 }, 528 { 529 name: "zero_flags_number", 530 input: `0`, 531 flags: UseNumber, 532 want: json.Number(`0`), 533 }, 534 { 535 name: "max_uint64_flags_default", 536 input: fmt.Sprint(uint64(math.MaxUint64)), 537 flags: 0, 538 want: float64(math.MaxUint64), 539 }, 540 { 541 name: "max_uint64_flags_int_uint_bigint_number", 542 input: fmt.Sprint(uint64(math.MaxUint64)), 543 flags: UseInt64 | UseUint64 | UseBigInt | UseNumber, 544 want: uint64(math.MaxUint64), 545 }, 546 { 547 name: "min_int64_flags_uint_int_bigint_number", 548 input: fmt.Sprint(int64(math.MinInt64)), 549 flags: UseInt64 | UseBigInt | UseNumber, 550 want: int64(math.MinInt64), 551 }, 552 { 553 name: "max_uint64_flags_int_bigint_number", 554 input: fmt.Sprint(uint64(math.MaxUint64)), 555 flags: UseInt64 | UseBigInt | UseNumber, 556 want: new(big.Int).SetUint64(math.MaxUint64), 557 }, 558 { 559 name: "overflow_uint64_flags_uint_int_bigint_number", 560 input: bigPos128.String(), 561 flags: UseUint64 | UseInt64 | UseBigInt | UseNumber, 562 want: bigPos128, 563 }, 564 { 565 name: "underflow_uint64_flags_uint_int_bigint_number", 566 input: bigNeg128.String(), 567 flags: UseUint64 | UseInt64 | UseBigInt | UseNumber, 568 want: bigNeg128, 569 }, 570 { 571 name: "overflow_uint64_flags_uint_int_number", 572 input: bigPos128.String(), 573 flags: UseUint64 | UseInt64 | UseNumber, 574 want: json.Number(bigPos128.String()), 575 }, 576 { 577 name: "underflow_uint64_flags_uint_int_number", 578 input: bigNeg128.String(), 579 flags: UseUint64 | UseInt64 | UseNumber, 580 want: json.Number(bigNeg128.String()), 581 }, 582 { 583 name: "overflow_uint64_flags_uint_int", 584 input: bigPos128.String(), 585 flags: UseUint64 | UseInt64, 586 want: float64(1 << 128), 587 }, 588 { 589 name: "underflow_uint64_flags_uint_int", 590 input: bigNeg128.String(), 591 flags: UseUint64 | UseInt64, 592 want: float64(-1 << 128), 593 }, 594 } 595 596 func TestParse_numeric(t *testing.T) { 597 t.Parallel() 598 599 for _, test := range numericParseTests { 600 test := test 601 602 t.Run(test.name, func(t *testing.T) { 603 t.Parallel() 604 605 var got any 606 607 rem, err := Parse([]byte(test.input), &got, test.flags) 608 if err != nil { 609 format := "Parse(%#q, ..., %#b) = %q [error], want nil" 610 t.Errorf(format, test.input, test.flags, err) 611 } 612 613 if len(rem) != 0 { 614 format := "Parse(%#q, ..., %#b) = %#q, want zero length" 615 t.Errorf(format, test.input, test.flags, rem) 616 } 617 618 if !reflect.DeepEqual(got, test.want) { 619 format := "Parse(%#q, %#b) -> %T(%#[3]v), want %T(%#[4]v)" 620 t.Errorf(format, test.input, test.flags, got, test.want) 621 } 622 }) 623 } 624 } 625 626 func newValue(model interface{}) reflect.Value { 627 if model == nil { 628 return reflect.New(reflect.TypeOf(&model).Elem()) 629 } 630 return reflect.New(reflect.TypeOf(model)) 631 } 632 633 func BenchmarkMarshal(b *testing.B) { 634 j := make([]byte, 0, 128*1024) 635 636 for _, v := range testValues { 637 b.Run(testName(v), func(b *testing.B) { 638 if marshal == nil { 639 return 640 } 641 642 for i := 0; i != b.N; i++ { 643 j, _ = marshal(j[:0], v) 644 } 645 646 b.SetBytes(int64(len(j))) 647 }) 648 } 649 } 650 651 func BenchmarkUnmarshal(b *testing.B) { 652 for _, v := range testValues { 653 b.Run(testName(v), func(b *testing.B) { 654 if unmarshal == nil { 655 return 656 } 657 658 x := v 659 if d, ok := x.(time.Duration); ok { 660 x = duration(d) 661 } 662 663 j, _ := json.Marshal(x) 664 x = newValue(v).Interface() 665 666 for i := 0; i != b.N; i++ { 667 unmarshal(j, x) 668 } 669 670 b.SetBytes(int64(len(j))) 671 }) 672 } 673 } 674 675 type buffer struct{ data []byte } 676 677 func (buf *buffer) Write(b []byte) (int, error) { 678 buf.data = append(buf.data, b...) 679 return len(b), nil 680 } 681 682 func (buf *buffer) WriteString(s string) (int, error) { 683 buf.data = append(buf.data, s...) 684 return len(s), nil 685 } 686 687 type jsonValue struct { 688 x int32 689 y int32 690 } 691 692 func (v jsonValue) MarshalJSON() ([]byte, error) { 693 return Marshal([2]int32{v.x, v.y}) 694 } 695 696 func (v *jsonValue) UnmarshalJSON(b []byte) error { 697 var a [2]int32 698 err := Unmarshal(b, &a) 699 v.x = a[0] 700 v.y = a[1] 701 return err 702 } 703 704 type textValue struct { 705 x int32 706 y int32 707 } 708 709 func (v textValue) MarshalText() ([]byte, error) { 710 return []byte(fmt.Sprintf("(%d,%d)", v.x, v.y)), nil 711 } 712 713 func (v *textValue) UnmarshalText(b []byte) error { 714 _, err := fmt.Sscanf(string(b), "(%d,%d)", &v.x, &v.y) 715 return err 716 } 717 718 type duration time.Duration 719 720 func (d duration) MarshalJSON() ([]byte, error) { 721 return []byte(`"` + time.Duration(d).String() + `"`), nil 722 } 723 724 func (d *duration) UnmarshalJSON(b []byte) error { 725 var s string 726 if err := json.Unmarshal(b, &s); err != nil { 727 return err 728 } 729 x, err := time.ParseDuration(s) 730 *d = duration(x) 731 return err 732 } 733 734 var ( 735 _ Marshaler = jsonValue{} 736 _ Marshaler = duration(0) 737 738 _ encoding.TextMarshaler = textValue{} 739 740 _ Unmarshaler = (*jsonValue)(nil) 741 _ Unmarshaler = (*duration)(nil) 742 743 _ encoding.TextUnmarshaler = (*textValue)(nil) 744 ) 745 746 func TestDecodeStructFieldCaseInsensitive(t *testing.T) { 747 b := []byte(`{ "type": "changed" }`) 748 s := struct { 749 Type string 750 }{"unchanged"} 751 752 if err := Unmarshal(b, &s); err != nil { 753 t.Error(err) 754 } 755 756 if s.Type != "changed" { 757 t.Error("s.Type: expected to be changed but found", s.Type) 758 } 759 } 760 761 func TestDecodeLines(t *testing.T) { 762 tests := []struct { 763 desc string 764 reader io.Reader 765 expectCount int 766 }{ 767 768 // simple 769 770 { 771 desc: "bare object", 772 reader: strings.NewReader("{\"Good\":true}"), 773 expectCount: 1, 774 }, 775 { 776 desc: "multiple objects on one line", 777 reader: strings.NewReader("{\"Good\":true}{\"Good\":true}\n"), 778 expectCount: 2, 779 }, 780 { 781 desc: "object spanning multiple lines", 782 reader: strings.NewReader("{\n\"Good\":true\n}\n"), 783 expectCount: 1, 784 }, 785 786 // whitespace handling 787 788 { 789 desc: "trailing newline", 790 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n"), 791 expectCount: 2, 792 }, 793 { 794 desc: "multiple trailing newlines", 795 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n\n"), 796 expectCount: 2, 797 }, 798 { 799 desc: "blank lines", 800 reader: strings.NewReader("{\"Good\":true}\n\n{\"Good\":true}"), 801 expectCount: 2, 802 }, 803 { 804 desc: "no trailing newline", 805 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}"), 806 expectCount: 2, 807 }, 808 { 809 desc: "leading whitespace", 810 reader: strings.NewReader(" {\"Good\":true}\n\t{\"Good\":true}"), 811 expectCount: 2, 812 }, 813 814 // multiple reads 815 816 { 817 desc: "one object, multiple reads", 818 reader: io.MultiReader( 819 strings.NewReader("{"), 820 strings.NewReader("\"Good\": true"), 821 strings.NewReader("}\n"), 822 ), 823 expectCount: 1, 824 }, 825 826 // EOF reads 827 828 { 829 desc: "one object + EOF", 830 reader: &eofReader{"{\"Good\":true}\n"}, 831 expectCount: 1, 832 }, 833 { 834 desc: "leading whitespace + EOF", 835 reader: &eofReader{"\n{\"Good\":true}\n"}, 836 expectCount: 1, 837 }, 838 { 839 desc: "multiple objects + EOF", 840 reader: &eofReader{"{\"Good\":true}\n{\"Good\":true}\n"}, 841 expectCount: 2, 842 }, 843 { 844 desc: "one object + multiple reads + EOF", 845 reader: io.MultiReader( 846 strings.NewReader("{"), 847 strings.NewReader(" \"Good\": true"), 848 &eofReader{"}\n"}, 849 ), 850 expectCount: 1, 851 }, 852 { 853 desc: "multiple objects + multiple reads + EOF", 854 reader: io.MultiReader( 855 strings.NewReader("{"), 856 strings.NewReader(" \"Good\": true}{\"Good\": true}"), 857 &eofReader{"\n"}, 858 ), 859 expectCount: 2, 860 }, 861 862 { 863 // the 2nd object should be discarded, as 42 cannot be cast to bool 864 desc: "unmarshal error while decoding", 865 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n{\"Good\":true}\n"), 866 expectCount: 2, 867 }, 868 { 869 // the 2nd object should be discarded, as 42 cannot be cast to bool 870 desc: "unmarshal error while decoding last object", 871 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n"), 872 expectCount: 1, 873 }, 874 } 875 876 type obj struct { 877 Good bool 878 } 879 880 for _, test := range tests { 881 t.Run(test.desc, func(t *testing.T) { 882 d := NewDecoder(test.reader) 883 var count int 884 var err error 885 for { 886 var o obj 887 err = d.Decode(&o) 888 if err != nil { 889 if err == io.EOF { 890 break 891 } 892 893 switch err.(type) { 894 case *SyntaxError, *UnmarshalTypeError, *UnmarshalFieldError: 895 t.Log("unmarshal error", err) 896 continue 897 } 898 899 t.Error("decode error", err) 900 break 901 } 902 if !o.Good { 903 t.Errorf("object was not unmarshaled correctly: %#v", o) 904 } 905 count++ 906 } 907 908 if err != nil && err != io.EOF { 909 t.Error(err) 910 } 911 912 if count != test.expectCount { 913 t.Errorf("expected %d objects, got %d", test.expectCount, count) 914 } 915 }) 916 } 917 } 918 919 // eofReader is a simple io.Reader that reads its full contents _and_ returns 920 // and EOF in the first call. Subsequent Read calls only return EOF. 921 type eofReader struct { 922 s string 923 } 924 925 func (r *eofReader) Read(p []byte) (n int, err error) { 926 n = copy(p, r.s) 927 r.s = r.s[n:] 928 if r.s == "" { 929 err = io.EOF 930 } 931 return 932 } 933 934 func TestDontMatchCaseIncensitiveStructFields(t *testing.T) { 935 b := []byte(`{ "type": "changed" }`) 936 s := struct { 937 Type string 938 }{"unchanged"} 939 940 if _, err := Parse(b, &s, DontMatchCaseInsensitiveStructFields); err != nil { 941 t.Error(err) 942 } 943 944 if s.Type != "unchanged" { 945 t.Error("s.Type: expected to be unchanged but found", s.Type) 946 } 947 } 948 949 func TestMarshalFuzzBugs(t *testing.T) { 950 tests := []struct { 951 value interface{} 952 output string 953 }{ 954 { // html sequences are escaped even in RawMessage 955 value: struct { 956 P RawMessage 957 }{P: RawMessage(`"<"`)}, 958 output: "{\"P\":\"\\u003c\"}", 959 }, 960 { // raw message output is compacted 961 value: struct { 962 P RawMessage 963 }{P: RawMessage(`{"" :{}}`)}, 964 output: "{\"P\":{\"\":{}}}", 965 }, 966 } 967 968 for _, test := range tests { 969 t.Run("", func(t *testing.T) { 970 b, err := Marshal(test.value) 971 if err != nil { 972 t.Fatal(err) 973 } 974 975 if string(b) != test.output { 976 t.Error("values mismatch") 977 t.Logf("expected: %#v", test.output) 978 t.Logf("found: %#v", string(b)) 979 } 980 }) 981 } 982 } 983 984 func TestUnmarshalFuzzBugs(t *testing.T) { 985 tests := []struct { 986 input string 987 value interface{} 988 }{ 989 { // non-UTF8 sequences must be converted to the utf8.RuneError character. 990 input: "[\"00000\xef\"]", 991 value: []interface{}{"00000�"}, 992 }, 993 { // UTF16 surrogate followed by null character 994 input: "[\"\\ud800\\u0000\"]", 995 value: []interface{}{"�\x00"}, 996 }, 997 { // UTF16 surrogate followed by ascii character 998 input: "[\"\\uDF00\\u000e\"]", 999 value: []interface{}{"�\x0e"}, 1000 }, 1001 { // UTF16 surrogate followed by unicode character 1002 input: "[[\"\\uDF00\\u0800\"]]", 1003 value: []interface{}{[]interface{}{"�ࠀ"}}, 1004 }, 1005 { // invalid UTF16 surrogate sequenced followed by a valid UTF16 surrogate sequence 1006 input: "[\"\\udf00\\udb00\\udf00\"]", 1007 value: []interface{}{"�\U000d0300"}, 1008 }, 1009 { // decode single-element slice into []byte field 1010 input: "{\"f\":[0],\"0\":[0]}", 1011 value: struct{ F []byte }{F: []byte{0}}, 1012 }, 1013 { // decode multi-element slice into []byte field 1014 input: "{\"F\":[3,1,1,1,9,9]}", 1015 value: struct{ F []byte }{F: []byte{3, 1, 1, 1, 9, 9}}, 1016 }, 1017 { // decode string with escape sequence into []byte field 1018 input: "{\"F\":\"0p00\\r\"}", 1019 value: struct{ F []byte }{F: []byte("ҝ4")}, 1020 }, 1021 { // decode unicode code points which fold into ascii characters 1022 input: "{\"ſ\":\"8\"}", 1023 value: struct { 1024 S int `json:",string"` 1025 }{S: 8}, 1026 }, 1027 { // decode unicode code points which don't fold into ascii characters 1028 input: "{\"İ\":\"\"}", 1029 value: struct{ I map[string]string }{I: nil}, 1030 }, 1031 { // override pointer-to-pointer field clears the inner pointer only 1032 input: "{\"o\":0,\"o\":null}", 1033 value: struct{ O **int }{O: new(*int)}, 1034 }, 1035 { // subsequent occurrences of a map field retain keys previously loaded 1036 input: "{\"i\":{\"\":null},\"i\":{}}", 1037 value: struct{ I map[string]string }{I: map[string]string{"": ""}}, 1038 }, 1039 { // an empty string is an invalid JSON input 1040 input: "", 1041 }, 1042 { // ASCII character below 0x20 are invalid JSON input 1043 input: "[\"\b\"]", 1044 }, 1045 { // random byte before any value 1046 input: "\xad", 1047 }, 1048 { // cloud be the beginning of a false value but not 1049 input: "f", 1050 value: false, 1051 }, 1052 { // random ASCII character 1053 input: "}", 1054 value: []interface{}{}, 1055 }, 1056 { // random byte after valid JSON, decoded to a nil type 1057 input: "0\x93", 1058 }, 1059 { // random byte after valid JSON, decoded to a int type 1060 input: "0\x93", 1061 value: 0, 1062 }, 1063 { // random byte after valid JSON, decoded to a slice type 1064 input: "0\x93", 1065 value: []interface{}{}, 1066 }, 1067 { // decode integer into slice 1068 input: "0", 1069 value: []interface{}{}, 1070 }, 1071 { // decode integer with trailing space into slice 1072 input: "0\t", 1073 value: []interface{}{}, 1074 }, 1075 { // decode integer with leading random bytes into slice 1076 input: "\b0", 1077 value: []interface{}{}, 1078 }, 1079 { // decode string into slice followed by number 1080 input: "\"\"0", 1081 value: []interface{}{}, 1082 }, 1083 { // decode what looks like an object followed by a number into a string 1084 input: "{0", 1085 value: "", 1086 }, 1087 { // decode what looks like an object followed by a number into a map 1088 input: "{0", 1089 value: map[string]string{}, 1090 }, 1091 { // decode string into string with trailing random byte 1092 input: "\"\"\f", 1093 value: "", 1094 }, 1095 { // decode weird number value into nil 1096 input: "-00", 1097 }, 1098 { // decode an invalid escaped sequence 1099 input: "\"\\0\"", 1100 value: "", 1101 }, 1102 { // decode what looks like an array followed by a number into a slice 1103 input: "[9E600", 1104 value: []interface{}{}, 1105 }, 1106 { // decode a number which is too large to fit in a float64 1107 input: "[1e900]", 1108 value: []interface{}{}, 1109 }, 1110 { // many nested arrays openings 1111 input: "[[[[[[", 1112 value: []interface{}{}, 1113 }, 1114 { // decode a map with value type mismatch and missing closing character 1115 input: "{\"\":0", 1116 value: map[string]string{}, 1117 }, 1118 { // decode a struct with value type mismatch and missing closing character 1119 input: "{\"E\":\"\"", 1120 value: struct{ E uint8 }{}, 1121 }, 1122 { // decode a map with value type mismatch 1123 input: "{\"\":0}", 1124 value: map[string]string{}, 1125 }, 1126 { // decode number with exponent into integer field 1127 input: "{\"e\":0e0}", 1128 value: struct{ E uint8 }{}, 1129 }, 1130 { // decode invalid integer representation into integer field 1131 input: "{\"e\":00}", 1132 value: struct{ E uint8 }{}, 1133 }, 1134 { // decode unterminated array into byte slice 1135 input: "{\"F\":[", 1136 value: struct{ F []byte }{}, 1137 }, 1138 { // attempt to decode string into in 1139 input: "{\"S\":\"\"}", 1140 value: struct { 1141 S int `json:",string"` 1142 }{}, 1143 }, 1144 { // decode object with null key into map 1145 input: "{null:0}", 1146 value: map[string]interface{}{}, 1147 }, 1148 { // decode unquoted integer into struct field with string tag 1149 input: "{\"S\":0}", 1150 value: struct { 1151 S int `json:",string"` 1152 }{}, 1153 }, 1154 { // invalid base64 content when decoding string into byte slice 1155 input: "{\"F\":\"0\"}", 1156 value: struct{ F []byte }{}, 1157 }, 1158 { // decode an object with a "null" string as key 1159 input: "{\"null\":null}", 1160 value: struct { 1161 S int `json:",string"` 1162 }{}, 1163 }, 1164 { // decode an invalid floating point number representation into an integer field with string tag 1165 input: "{\"s\":8e800}", 1166 value: struct { 1167 S int `json:",string"` 1168 }{}, 1169 }, 1170 { // decode a string with leading zeroes into an integer field with string tag 1171 input: "{\"S\":\"00\"}", 1172 value: struct { 1173 S int `json:",string"` 1174 }{}, 1175 }, 1176 { // decode a string with invalid leading sign and zeroes into an integer field with string tag 1177 input: "{\"S\":\"+00\"}", 1178 value: struct { 1179 S int `json:",string"` 1180 }{}, 1181 }, 1182 { // decode a string with valid leading sign and zeroes into an integer field with string tag 1183 input: "{\"S\":\"-00\"}", 1184 value: struct { 1185 S int `json:",string"` 1186 }{}, 1187 }, 1188 { // decode non-ascii string into integer field with string tag 1189 input: "{\"ſ\":\"\xbf\"}", 1190 value: struct { 1191 S int `json:",string"` 1192 }{}, 1193 }, 1194 { // decode a valid floating point number representation into an integer field with string tag 1195 input: "{\"S\":0.0}", 1196 value: struct { 1197 S int `json:",string"` 1198 }{}, 1199 }, 1200 { // decode string with invalid leading sign to integer field with string tag 1201 input: "{\"S\":\"+0\"}", 1202 value: struct { 1203 S int `json:",string"` 1204 }{}, 1205 }, 1206 { // decode string with valid leading sign to integer field with string tag 1207 input: "{\"S\":\"-0\"}", 1208 value: struct { 1209 S int `json:",string"` 1210 }{}, 1211 }, 1212 { // decode string with object representation to integer field with string tag 1213 input: "{\"s\":{}}", 1214 value: struct { 1215 S int `json:",string"` 1216 }{}, 1217 }, 1218 { // decoding integer with leading zeroes 1219 input: "{\"o\":00}", 1220 value: struct{ O **int }{}, 1221 }, 1222 { // codeding string with invalid float representation into integer field with string tag 1223 input: "{\"s\":\"0.\"}", 1224 value: struct { 1225 S int `json:",string"` 1226 }{}, 1227 }, 1228 { // malformed negative integer in object value 1229 input: "{\"N\":-00}", 1230 value: struct{ N *int }{}, 1231 }, 1232 { // integer overflow 1233 input: "{\"a\":9223372036854775808}", 1234 value: struct { 1235 A int `json:",omitempty"` 1236 }{}, 1237 }, 1238 { // decode string with number followed by random byte into integer field with string tag 1239 input: "{\"s\":\"0]\"}", 1240 value: struct { 1241 S int `json:",string"` 1242 }{}, 1243 }, 1244 { // decode object into integer field 1245 input: "{\"n\":{}}", 1246 value: struct{ N *int }{}, 1247 }, 1248 { // decode negative integer into unsigned type 1249 input: "{\"E\":-0}", 1250 value: struct{ E uint8 }{}, 1251 }, 1252 { // decode string with number followed by random byte into integer field with string tag 1253 input: "{\"s\":\"03�\"}", 1254 value: struct { 1255 S int `json:",string"` 1256 }{}, 1257 }, 1258 { // decode string with leading zeroes into integer field with string tag 1259 input: "{\"s\":\"03\"}", 1260 value: struct { 1261 S int `json:",string"` 1262 }{S: 3}, 1263 }, 1264 { // decode string containing what looks like an object into integer field with string tag 1265 input: "{\"S\":\"{}\"}", 1266 value: struct { 1267 S int `json:",string"` 1268 }{}, 1269 }, 1270 { // decode an empty string followed by the same field with a null value into a byte slice 1271 input: "{\"F\":\"\",\"F\":null}", 1272 value: struct{ F []byte }{}, 1273 }, 1274 { // decode string containing a float into an integer field with string tag 1275 input: "{\"S\":\"0e0\"}", 1276 value: struct { 1277 S int `json:",string"` 1278 }{}, 1279 }, 1280 { // decode string with negative sign into a an integer field with string tag 1281 input: "{\"s\":\"-\"}", 1282 value: struct { 1283 S int `json:",string"` 1284 }{}, 1285 }, 1286 { // decode string with positive sign into a an integer field with string tag 1287 input: "{\"s\":\"+\"}", 1288 value: struct { 1289 S int `json:",string"` 1290 }{}, 1291 }, 1292 { // decode an integer into a json unmarshaler 1293 input: "{\"q\":0}", 1294 value: struct { 1295 Q testMarshaller 1296 }{}, 1297 }, 1298 // This test fails because it appears that the encoding/json package 1299 // will decode "q" before "s", so it returns an error about "q" being of 1300 // the wrong type while this package will prase object keys in the order 1301 // that they appear in the JSON input, so it detects the error from "s" 1302 // first. 1303 // 1304 //{ 1305 // input: "{\"s\":0,\"q\":0}", 1306 // value: struct { 1307 // Q testMarshaller 1308 // S int `json:",string"` 1309 // }{}, 1310 //}, 1311 } 1312 1313 for _, test := range tests { 1314 t.Run("", func(t *testing.T) { 1315 var ptr1 interface{} 1316 var ptr2 interface{} 1317 1318 if test.value != nil { 1319 ptr1 = reflect.New(reflect.TypeOf(test.value)).Interface() 1320 ptr2 = reflect.New(reflect.TypeOf(test.value)).Interface() 1321 } 1322 1323 err1 := json.Unmarshal([]byte(test.input), ptr1) 1324 err2 := Unmarshal([]byte(test.input), ptr2) 1325 1326 if reflect.TypeOf(err1) != reflect.TypeOf(err2) { 1327 t.Error("errors mismatch") 1328 t.Logf("expected: %T: %v", err1, err1) 1329 t.Logf("found: %T: %v", err2, err2) 1330 } else if err1 == nil && test.value != nil { 1331 if value := reflect.ValueOf(ptr2).Elem().Interface(); !reflect.DeepEqual(test.value, value) { 1332 t.Error("values mismatch") 1333 t.Logf("expected: %#v", test.value) 1334 t.Logf("found: %#v", value) 1335 } 1336 } 1337 }) 1338 } 1339 } 1340 1341 func BenchmarkEasyjsonUnmarshalSmallStruct(b *testing.B) { 1342 type Hashtag struct { 1343 Indices []int `json:"indices"` 1344 Text string `json:"text"` 1345 } 1346 1347 //easyjson:json 1348 type Entities struct { 1349 Hashtags []Hashtag `json:"hashtags"` 1350 Urls []*string `json:"urls"` 1351 UserMentions []*string `json:"user_mentions"` 1352 } 1353 1354 var json = []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`) 1355 1356 for i := 0; i < b.N; i++ { 1357 var value Entities 1358 if err := Unmarshal(json, &value); err != nil { 1359 b.Fatal(err) 1360 } 1361 } 1362 } 1363 1364 type testMarshaller struct { 1365 v string 1366 } 1367 1368 func (m *testMarshaller) MarshalJSON() ([]byte, error) { 1369 return Marshal(m.v) 1370 } 1371 1372 func (m *testMarshaller) UnmarshalJSON(data []byte) error { 1373 return Unmarshal(data, &m.v) 1374 } 1375 1376 func TestGithubIssue11(t *testing.T) { 1377 // https://github.com/segmentio/encoding/issues/11 1378 v := struct{ F float64 }{ 1379 F: math.NaN(), 1380 } 1381 1382 _, err := Marshal(v) 1383 if err == nil { 1384 t.Error("no error returned when marshalling NaN value") 1385 } else if s := err.Error(); !strings.Contains(s, "NaN") { 1386 t.Error("error returned when marshalling NaN value does not mention 'NaN':", s) 1387 } else { 1388 t.Log(s) 1389 } 1390 } 1391 1392 type Issue13 struct { 1393 Stringer fmt.Stringer 1394 Field int `json:"MyInt"` 1395 } 1396 1397 type S string 1398 1399 func (s S) String() string { return string(s) } 1400 1401 func TestGithubIssue13(t *testing.T) { 1402 // https://github.com/segmentio/encoding/issues/13 1403 v := Issue13{} 1404 1405 b, err := Marshal(v) 1406 if err != nil { 1407 t.Error("unexpected errror:", err) 1408 } else { 1409 t.Log(string(b)) 1410 } 1411 1412 v = Issue13{Stringer: S("")} 1413 if err := Unmarshal([]byte(`{"Stringer":null}`), &v); err != nil { 1414 t.Error("unexpected error:", err) 1415 } 1416 if v.Stringer != nil { 1417 t.Error("Stringer field was not overwritten") 1418 } 1419 1420 v = Issue13{} 1421 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1422 t.Error("expected error but decoding string value into nil fmt.Stringer but got <nil>") 1423 } 1424 1425 v = Issue13{Stringer: S("")} 1426 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1427 t.Error("expected error but decoding string value into non-pointer fmt.Stringer but got <nil>") 1428 } 1429 1430 s := S("") 1431 v = Issue13{Stringer: &s} 1432 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err != nil { 1433 t.Error("unexpected error decoding string value into pointer fmt.Stringer:", err) 1434 } 1435 } 1436 1437 func TestGithubIssue15(t *testing.T) { 1438 // https://github.com/segmentio/encoding/issues/15 1439 tests := []struct { 1440 m interface{} 1441 s string 1442 }{ 1443 { 1444 m: map[uint]bool{1: true, 123: true, 333: true, 42: true}, 1445 s: `{"1":true,"123":true,"333":true,"42":true}`, 1446 }, 1447 { 1448 m: map[int]bool{-1: true, -123: true, 333: true, 42: true}, 1449 s: `{"-1":true,"-123":true,"333":true,"42":true}`, 1450 }, 1451 } 1452 1453 for _, test := range tests { 1454 b, _ := Marshal(test.m) 1455 1456 if string(b) != test.s { 1457 t.Error("map with integer keys must be ordered by their string representation, got", string(b)) 1458 } 1459 1460 } 1461 } 1462 1463 type sliceA []byte 1464 1465 func (sliceA) MarshalJSON() ([]byte, error) { 1466 return []byte(`"A"`), nil 1467 } 1468 1469 type sliceB []byte 1470 1471 func (sliceB) MarshalText() ([]byte, error) { 1472 return []byte("B"), nil 1473 } 1474 1475 type mapA map[string]string 1476 1477 func (mapA) MarshalJSON() ([]byte, error) { 1478 return []byte(`"A"`), nil 1479 } 1480 1481 type mapB map[string]string 1482 1483 func (mapB) MarshalText() ([]byte, error) { 1484 return []byte("B"), nil 1485 } 1486 1487 type intPtrA int 1488 1489 func (*intPtrA) MarshalJSON() ([]byte, error) { 1490 return []byte(`"A"`), nil 1491 } 1492 1493 type intPtrB int 1494 1495 func (*intPtrB) MarshalText() ([]byte, error) { 1496 return []byte("B"), nil 1497 } 1498 1499 type structA struct{ I intPtrA } 1500 type structB struct{ I intPtrB } 1501 type structC struct{ M Marshaler } 1502 type structD struct{ M encoding.TextMarshaler } 1503 1504 func TestGithubIssue16(t *testing.T) { 1505 // https://github.com/segmentio/encoding/issues/16 1506 tests := []struct { 1507 value interface{} 1508 output string 1509 }{ 1510 {value: sliceA(nil), output: `"A"`}, 1511 {value: sliceB(nil), output: `"B"`}, 1512 {value: mapA(nil), output: `"A"`}, 1513 {value: mapB(nil), output: `"B"`}, 1514 {value: intPtrA(1), output: `1`}, 1515 {value: intPtrB(2), output: `2`}, 1516 {value: new(intPtrA), output: `"A"`}, 1517 {value: new(intPtrB), output: `"B"`}, 1518 {value: (*intPtrA)(nil), output: `null`}, 1519 {value: (*intPtrB)(nil), output: `null`}, 1520 {value: structA{I: 1}, output: `{"I":1}`}, 1521 {value: structB{I: 2}, output: `{"I":2}`}, 1522 {value: structC{}, output: `{"M":null}`}, 1523 {value: structD{}, output: `{"M":null}`}, 1524 {value: &structA{I: 1}, output: `{"I":"A"}`}, 1525 {value: &structB{I: 2}, output: `{"I":"B"}`}, 1526 {value: &structC{}, output: `{"M":null}`}, 1527 {value: &structD{}, output: `{"M":null}`}, 1528 } 1529 1530 for _, test := range tests { 1531 t.Run(fmt.Sprintf("%T", test.value), func(t *testing.T) { 1532 if b, _ := Marshal(test.value); string(b) != test.output { 1533 t.Errorf(`%s != %s`, string(b), test.output) 1534 } 1535 }) 1536 } 1537 } 1538 1539 func TestDecoderInputOffset(t *testing.T) { 1540 checkOffset := func(o, expected int64) { 1541 if o != expected { 1542 t.Error("unexpected input offset", o, expected) 1543 } 1544 } 1545 1546 b := []byte(`{"userId": "blah"}{"userId": "blah"} 1547 {"userId": "blah"}{"num": 0}`) 1548 d := NewDecoder(bytes.NewReader(b)) 1549 1550 var expected int64 1551 checkOffset(d.InputOffset(), expected) 1552 1553 var a struct { 1554 UserId string `json:"userId"` 1555 } 1556 1557 if err := d.Decode(&a); err != nil { 1558 t.Error("unexpected decode error", err) 1559 } 1560 expected = int64(18) 1561 checkOffset(d.InputOffset(), expected) 1562 1563 if err := d.Decode(&a); err != nil { 1564 t.Error("unexpected decode error", err) 1565 } 1566 expected = int64(38) 1567 checkOffset(d.InputOffset(), expected) 1568 1569 if err := d.Decode(&a); err != nil { 1570 t.Error("unexpected decode error", err) 1571 } 1572 expected = int64(56) 1573 checkOffset(d.InputOffset(), expected) 1574 1575 var z struct { 1576 Num int64 `json:"num"` 1577 } 1578 if err := d.Decode(&z); err != nil { 1579 t.Error("unexpected decode error", err) 1580 } 1581 expected = int64(66) 1582 checkOffset(d.InputOffset(), expected) 1583 } 1584 1585 func TestGithubIssue18(t *testing.T) { 1586 // https://github.com/segmentio/encoding/issues/18 1587 b := []byte(`{ 1588 "userId": "blah", 1589 }`) 1590 1591 d := NewDecoder(bytes.NewReader(b)) 1592 1593 var a struct { 1594 UserId string `json:"userId"` 1595 } 1596 switch err := d.Decode(&a).(type) { 1597 case *SyntaxError: 1598 default: 1599 t.Error("expected syntax error but found:", err) 1600 } 1601 1602 for i := 1; i <= 18; i++ { // up to the invalid ',' character 1603 d := NewDecoder(bytes.NewReader(b[:i])) // cut somewhere in the middle 1604 switch err := d.Decode(&a); err { 1605 case io.ErrUnexpectedEOF: 1606 default: 1607 t.Error("expected 'unexpected EOF' error but found:", err) 1608 } 1609 } 1610 } 1611 1612 func TestGithubIssue23(t *testing.T) { 1613 t.Run("marshal-1", func(t *testing.T) { 1614 type d struct{ S map[string]string } 1615 1616 b, _ := Marshal(map[string]d{"1": {S: map[string]string{"2": "3"}}}) 1617 if string(b) != `{"1":{"S":{"2":"3"}}}` { 1618 t.Error(string(b)) 1619 } 1620 }) 1621 1622 t.Run("marshal-2", func(t *testing.T) { 1623 type testInner struct { 1624 InnerMap map[string]string `json:"inner_map"` 1625 } 1626 1627 type testOuter struct { 1628 OuterMap map[string]testInner `json:"outer_map"` 1629 } 1630 1631 b, _ := Marshal(testOuter{ 1632 OuterMap: map[string]testInner{ 1633 "outer": { 1634 InnerMap: map[string]string{"inner": "value"}, 1635 }, 1636 }, 1637 }) 1638 1639 if string(b) != `{"outer_map":{"outer":{"inner_map":{"inner":"value"}}}}` { 1640 t.Error(string(b)) 1641 } 1642 }) 1643 1644 t.Run("marshal-3", func(t *testing.T) { 1645 type A struct{ A map[string]string } 1646 type B struct{ B map[string]A } 1647 type C struct{ C map[string]B } 1648 1649 b, _ := Marshal(C{ 1650 C: map[string]B{ 1651 "1": B{ 1652 B: map[string]A{ 1653 "2": A{ 1654 A: map[string]string{"3": "!"}, 1655 }, 1656 }, 1657 }, 1658 }, 1659 }) 1660 1661 if string(b) != `{"C":{"1":{"B":{"2":{"A":{"3":"!"}}}}}}` { 1662 t.Error(string(b)) 1663 } 1664 }) 1665 1666 t.Run("unmarshal-1", func(t *testing.T) { 1667 var d struct{ S map[string]string } 1668 1669 if err := Unmarshal([]byte(`{"1":{"S":{"2":"3"}}}`), &d); err != nil { 1670 t.Error(err) 1671 } 1672 }) 1673 } 1674 1675 func TestGithubIssue26(t *testing.T) { 1676 type interfaceType interface{} 1677 1678 var value interfaceType 1679 var data = []byte(`{}`) 1680 1681 if err := Unmarshal(data, &value); err != nil { 1682 t.Error(err) 1683 } 1684 } 1685 1686 func TestGithubIssue28(t *testing.T) { 1687 type A struct { 1688 Err error `json:"err"` 1689 } 1690 1691 if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil { 1692 t.Error(err) 1693 } else if string(b) != `{"err":{}}` { 1694 t.Error(string(b)) 1695 } 1696 1697 } 1698 1699 func TestGithubIssue41(t *testing.T) { 1700 expectedString := `{"Zero":0,"Three":3}` 1701 type M struct { 1702 One int 1703 Two int 1704 } 1705 type N struct { 1706 Zero int 1707 *M 1708 Three int 1709 } 1710 1711 if b, err := Marshal(N{Three: 3}); err != nil { 1712 t.Error(err) 1713 } else if string(b) != expectedString { 1714 t.Error( 1715 "got: ", string(b), 1716 "expected: ", expectedString, 1717 ) 1718 } 1719 1720 } 1721 1722 func TestGithubIssue44(t *testing.T) { 1723 var out rawJsonString 1724 if err := Unmarshal([]byte("null"), &out); err != nil { 1725 t.Fatal(err) 1726 } 1727 if out != "null" { 1728 t.Errorf("wanted \"null\" but got %q", out) 1729 } 1730 } 1731 1732 type issue107Foo struct { 1733 Bar *issue107Bar 1734 } 1735 1736 type issue107Bar struct { 1737 Foo *issue107Foo 1738 } 1739 1740 func TestGithubIssue107(t *testing.T) { 1741 f := &issue107Foo{} 1742 b := &issue107Bar{} 1743 f.Bar = b 1744 b.Foo = f 1745 1746 _, err := Marshal(f) // must not crash 1747 switch err.(type) { 1748 case *UnsupportedValueError: 1749 default: 1750 t.Errorf("marshaling a cycling data structure was expected to return an unsupported value error but got %T", err) 1751 } 1752 } 1753 1754 type rawJsonString string 1755 1756 func (r *rawJsonString) UnmarshalJSON(b []byte) error { 1757 if len(b) == 0 { 1758 *r = "null" 1759 } else { 1760 *r = rawJsonString(b) 1761 } 1762 return nil 1763 } 1764 1765 func TestSetTrustRawMessage(t *testing.T) { 1766 buf := &bytes.Buffer{} 1767 enc := NewEncoder(buf) 1768 enc.SetTrustRawMessage(true) 1769 1770 // "Good" values are encoded in the regular way 1771 m := map[string]json.RawMessage{ 1772 "k": json.RawMessage(`"value"`), 1773 } 1774 if err := enc.Encode(m); err != nil { 1775 t.Error(err) 1776 } 1777 1778 b := buf.Bytes() 1779 exp := []byte(`{"k":"value"}`) 1780 exp = append(exp, '\n') 1781 if bytes.Compare(exp, b) != 0 { 1782 t.Error( 1783 "unexpected encoding:", 1784 "expected", exp, 1785 "got", b, 1786 ) 1787 } 1788 1789 // "Bad" values are encoded without checking and throwing an error 1790 buf.Reset() 1791 m = map[string]json.RawMessage{ 1792 "k": json.RawMessage(`bad"value`), 1793 } 1794 if err := enc.Encode(m); err != nil { 1795 t.Error(err) 1796 } 1797 1798 b = buf.Bytes() 1799 exp = []byte(`{"k":bad"value}`) 1800 exp = append(exp, '\n') 1801 if bytes.Compare(exp, b) != 0 { 1802 t.Error( 1803 "unexpected encoding:", 1804 "expected", exp, 1805 "got", b, 1806 ) 1807 } 1808 } 1809 1810 func TestSetAppendNewline(t *testing.T) { 1811 buf := &bytes.Buffer{} 1812 enc := NewEncoder(buf) 1813 1814 m := "value" 1815 1816 // Default encoding adds an extra newline 1817 if err := enc.Encode(m); err != nil { 1818 t.Error(err) 1819 } 1820 b := buf.Bytes() 1821 exp := []byte(`"value"`) 1822 exp = append(exp, '\n') 1823 if bytes.Compare(exp, b) != 0 { 1824 t.Error( 1825 "unexpected encoding:", 1826 "expected", exp, 1827 "got", b, 1828 ) 1829 } 1830 1831 // With SetAppendNewline(false), there shouldn't be a newline in the output 1832 buf.Reset() 1833 enc.SetAppendNewline(false) 1834 if err := enc.Encode(m); err != nil { 1835 t.Error(err) 1836 } 1837 b = buf.Bytes() 1838 exp = []byte(`"value"`) 1839 if bytes.Compare(exp, b) != 0 { 1840 t.Error( 1841 "unexpected encoding:", 1842 "expected", exp, 1843 "got", b, 1844 ) 1845 } 1846 } 1847 1848 func TestEscapeString(t *testing.T) { 1849 b := Escape(`value`) 1850 x := []byte(`"value"`) 1851 1852 if !bytes.Equal(x, b) { 1853 t.Error( 1854 "unexpected encoding:", 1855 "expected", string(x), 1856 "got", string(b), 1857 ) 1858 } 1859 } 1860 1861 func TestAppendEscape(t *testing.T) { 1862 t.Run("basic", func(t *testing.T) { 1863 b := AppendEscape([]byte{}, `value`, AppendFlags(0)) 1864 exp := []byte(`"value"`) 1865 if bytes.Compare(exp, b) != 0 { 1866 t.Error( 1867 "unexpected encoding:", 1868 "expected", exp, 1869 "got", b, 1870 ) 1871 } 1872 }) 1873 1874 t.Run("escaped", func(t *testing.T) { 1875 b := AppendEscape([]byte{}, `"escaped" <value>`, EscapeHTML) 1876 exp := []byte(`"\"escaped\"\t\u003cvalue\u003e"`) 1877 if bytes.Compare(exp, b) != 0 { 1878 t.Error( 1879 "unexpected encoding:", 1880 "expected", exp, 1881 "got", b, 1882 ) 1883 } 1884 }) 1885 1886 t.Run("build", func(t *testing.T) { 1887 b := []byte{} 1888 b = append(b, '{') 1889 b = AppendEscape(b, `key`, EscapeHTML) 1890 b = append(b, ':') 1891 b = AppendEscape(b, `"escaped" <value>`, EscapeHTML) 1892 b = append(b, '}') 1893 exp := []byte(`{"key":"\"escaped\"\t\u003cvalue\u003e"}`) 1894 if bytes.Compare(exp, b) != 0 { 1895 t.Error( 1896 "unexpected encoding:", 1897 "expected", exp, 1898 "got", b, 1899 ) 1900 } 1901 }) 1902 } 1903 1904 func TestUnescapeString(t *testing.T) { 1905 b := Unescape([]byte(`"value"`)) 1906 x := []byte(`value`) 1907 1908 if !bytes.Equal(x, b) { 1909 t.Error( 1910 "unexpected decoding:", 1911 "expected", string(x), 1912 "got", string(b), 1913 ) 1914 } 1915 } 1916 1917 func TestAppendUnescape(t *testing.T) { 1918 t.Run("basic", func(t *testing.T) { 1919 out := AppendUnescape([]byte{}, []byte(`"value"`), ParseFlags(0)) 1920 exp := []byte("value") 1921 if bytes.Compare(exp, out) != 0 { 1922 t.Error( 1923 "unexpected decoding:", 1924 "expected", exp, 1925 "got", out, 1926 ) 1927 } 1928 }) 1929 1930 t.Run("escaped", func(t *testing.T) { 1931 b := AppendUnescape([]byte{}, []byte(`"\"escaped\"\t\u003cvalue\u003e"`), ParseFlags(0)) 1932 exp := []byte(`"escaped" <value>`) 1933 if bytes.Compare(exp, b) != 0 { 1934 t.Error( 1935 "unexpected encoding:", 1936 "expected", exp, 1937 "got", b, 1938 ) 1939 } 1940 }) 1941 1942 t.Run("build", func(t *testing.T) { 1943 b := []byte{} 1944 b = append(b, []byte(`{"key":`)...) 1945 b = AppendUnescape(b, []byte(`"\"escaped\"\t\u003cvalue\u003e"`), ParseFlags(0)) 1946 b = append(b, '}') 1947 exp := []byte(`{"key":"escaped" <value>}`) 1948 if bytes.Compare(exp, b) != 0 { 1949 t.Error( 1950 "unexpected encoding:", 1951 "expected", string(exp), 1952 "got", string(b), 1953 ) 1954 } 1955 }) 1956 } 1957 1958 func BenchmarkUnescape(b *testing.B) { 1959 s := []byte(`"\"escaped\"\t\u003cvalue\u003e"`) 1960 out := []byte{} 1961 for i := 0; i < b.N; i++ { 1962 out = Unescape(s) 1963 } 1964 1965 b.Log(string(out)) 1966 } 1967 1968 func BenchmarkUnmarshalField(b *testing.B) { 1969 s := []byte(`"\"escaped\"\t\u003cvalue\u003e"`) 1970 var v string 1971 1972 for i := 0; i < b.N; i++ { 1973 json.Unmarshal(s, &v) 1974 } 1975 1976 b.Log(v) 1977 } 1978 1979 func TestKind(t *testing.T) { 1980 for _, test := range []struct { 1981 kind Kind 1982 class Kind 1983 }{ 1984 {kind: 0, class: 0}, 1985 {kind: Null, class: Null}, 1986 {kind: False, class: Bool}, 1987 {kind: True, class: Bool}, 1988 {kind: Num, class: Num}, 1989 {kind: Uint, class: Num}, 1990 {kind: Int, class: Num}, 1991 {kind: Float, class: Num}, 1992 {kind: String, class: String}, 1993 {kind: Unescaped, class: String}, 1994 {kind: Array, class: Array}, 1995 {kind: Object, class: Object}, 1996 } { 1997 if class := test.kind.Class(); class != test.class { 1998 t.Errorf("class of kind(%d) mismatch: want=%d got=%d", test.kind, test.class, class) 1999 } 2000 } 2001 }