github.com/neilotoole/jsoncolor@v0.7.2-0.20231115150201-1637fae69be1/json_test.go (about) 1 package jsoncolor 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "encoding" 7 "encoding/json" 8 "errors" 9 "flag" 10 "fmt" 11 "io" 12 "io/ioutil" 13 "math" 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, nil, nil) 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 testValues = [...]interface{}{ 90 // constants 91 nil, 92 false, 93 true, 94 95 // int 96 int(0), 97 int(1), 98 int(42), 99 int(-1), 100 int(-42), 101 int8(math.MaxInt8), 102 int8(math.MinInt8), 103 int16(math.MaxInt16), 104 int16(math.MinInt16), 105 int32(math.MaxInt32), 106 int32(math.MinInt32), 107 int64(math.MaxInt64), 108 int64(math.MinInt64), 109 110 // uint 111 uint(0), 112 uint(1), 113 uintptr(0), 114 uintptr(1), 115 uint8(math.MaxUint8), 116 uint16(math.MaxUint16), 117 uint32(math.MaxUint32), 118 uint64(math.MaxUint64), 119 120 // float 121 float32(0), 122 float32(0.5), 123 float32(math.SmallestNonzeroFloat32), 124 float32(math.MaxFloat32), 125 float64(0), 126 float64(0.5), 127 float64(math.SmallestNonzeroFloat64), 128 float64(math.MaxFloat64), 129 130 // number 131 Number("0"), 132 Number("1234567890"), 133 Number("-0.5"), 134 Number("-1e+2"), 135 136 // string 137 "", 138 "Hello World!", 139 "Hello\"World!", 140 "Hello\\World!", 141 "Hello\nWorld!", 142 "Hello\rWorld!", 143 "Hello\tWorld!", 144 "Hello\bWorld!", 145 "Hello\fWorld!", 146 "你好", 147 "<", 148 ">", 149 "&", 150 "\u001944", 151 "\u00c2e>", 152 "\u00c2V?", 153 "\u000e=8", 154 "\u001944\u00c2e>\u00c2V?\u000e=8", 155 "ir\u001bQJ\u007f\u0007y\u0015)", 156 strings.Repeat("A", 32), 157 strings.Repeat("A", 250), 158 strings.Repeat("A", 1020), 159 160 // bytes 161 []byte(""), 162 []byte("Hello World!"), 163 bytes.Repeat([]byte("A"), 250), 164 bytes.Repeat([]byte("A"), 1020), 165 166 // time 167 time.Unix(0, 0).In(time.UTC), 168 time.Unix(1, 42).In(time.UTC), 169 time.Unix(17179869184, 999999999).In(time.UTC), 170 time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), 171 172 // array 173 [...]int{}, 174 [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 175 176 // slice 177 []int{}, 178 []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 179 makeSlice(250), 180 makeSlice(1020), 181 []string{"A", "B", "C"}, 182 []interface{}{nil, true, false, 0.5, "Hello World!"}, 183 184 // map 185 makeMapStringBool(0), 186 makeMapStringBool(15), 187 makeMapStringBool(1020), 188 makeMapStringInterface(0), 189 makeMapStringInterface(15), 190 makeMapStringInterface(1020), 191 map[int]bool{1: false, 42: true}, 192 map[textValue]bool{{1, 2}: true, {3, 4}: false}, 193 map[string]*point{ 194 "A": {1, 2}, 195 "B": {3, 4}, 196 "C": {5, 6}, 197 }, 198 map[string]RawMessage{ 199 "A": RawMessage(`{}`), 200 "B": RawMessage(`null`), 201 "C": RawMessage(`42`), 202 }, 203 204 // struct 205 struct{}{}, 206 struct{ A int }{42}, 207 struct{ A, B, C int }{1, 2, 3}, 208 struct { 209 A int 210 T time.Time 211 S string 212 }{42, time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), "Hello World!"}, 213 // These types are interesting because they fit in a pointer so the compiler 214 // puts their value directly into the pointer field of the interface{} that 215 // is passed to Marshal. 216 struct{ X *int }{}, 217 struct{ X *int }{new(int)}, 218 struct{ X **int }{}, 219 // Struct types with more than one pointer, those exercise the regular 220 // pointer handling with code that dereferences the fields. 221 struct{ X, Y *int }{}, 222 struct{ X, Y *int }{new(int), new(int)}, 223 struct { 224 A string `json:"name"` 225 B string `json:"-"` 226 C string `json:",omitempty"` 227 D map[string]interface{} `json:",string"` 228 e string 229 }{A: "Luke", D: map[string]interface{}{"answer": float64(42)}}, 230 struct{ point }{point{1, 2}}, 231 tree{ 232 Value: "T", 233 Left: &tree{Value: "L"}, 234 Right: &tree{Value: "R", Left: &tree{Value: "R-L"}}, 235 }, 236 237 // pointer 238 (*string)(nil), 239 new(int), 240 241 // Marshaler/Unmarshaler 242 jsonValue{}, 243 jsonValue{1, 2}, 244 245 // encoding.TextMarshaler/encoding.TextUnmarshaler 246 textValue{}, 247 textValue{1, 2}, 248 249 // RawMessage 250 RawMessage(`{ 251 "answer": 42, 252 "hello": "world" 253 }`), 254 255 // fixtures 256 loadTestdata(filepath.Join(runtime.GOROOT(), "src/encoding/json/testdata/code.json.gz")), 257 } 258 259 var durationTestValues = []interface{}{ 260 // duration 261 time.Nanosecond, 262 time.Microsecond, 263 time.Millisecond, 264 time.Second, 265 time.Minute, 266 time.Hour, 267 268 // struct with duration 269 struct{ D1, D2 time.Duration }{time.Millisecond, time.Hour}, 270 } 271 272 func makeSlice(n int) []int { 273 s := make([]int, n) 274 for i := range s { 275 s[i] = i 276 } 277 return s 278 } 279 280 func makeMapStringBool(n int) map[string]bool { 281 m := make(map[string]bool, n) 282 for i := 0; i != n; i++ { 283 m[strconv.Itoa(i)] = true 284 } 285 return m 286 } 287 288 func makeMapStringInterface(n int) map[string]interface{} { 289 m := make(map[string]interface{}, n) 290 for i := 0; i != n; i++ { 291 m[strconv.Itoa(i)] = nil 292 } 293 return m 294 } 295 296 func testName(v interface{}) string { 297 return fmt.Sprintf("%T", v) 298 } 299 300 type codeResponse2 struct { 301 Tree *codeNode2 `json:"tree"` 302 Username string `json:"username"` 303 } 304 305 type codeNode2 struct { 306 Name string `json:"name"` 307 Kids []*codeNode `json:"kids"` 308 CLWeight float64 `json:"cl_weight"` 309 Touches int `json:"touches"` 310 MinT int64 `json:"min_t"` 311 MaxT int64 `json:"max_t"` 312 MeanT int64 `json:"mean_t"` 313 } 314 315 func loadTestdata(path string) interface{} { 316 f, err := os.Open(path) 317 if err != nil { 318 return err.Error() 319 } 320 defer f.Close() 321 322 r, err := gzip.NewReader(f) 323 if err != nil { 324 return err.Error() 325 } 326 defer r.Close() 327 328 testdata := new(codeResponse2) 329 if err := json.NewDecoder(r).Decode(testdata); err != nil { 330 return err.Error() 331 } 332 return testdata 333 } 334 335 func TestCodec(t *testing.T) { 336 for _, v1 := range testValues { 337 t.Run(testName(v1), func(t *testing.T) { 338 v2 := newValue(v1) 339 340 a, err := json.MarshalIndent(v1, "", "\t") 341 if err != nil { 342 t.Error(err) 343 return 344 } 345 a = append(a, '\n') 346 347 buf := &bytes.Buffer{} 348 enc := NewEncoder(buf) 349 enc.SetIndent("", "\t") 350 351 if err := enc.Encode(v1); err != nil { 352 t.Error(err) 353 return 354 } 355 b := buf.Bytes() 356 357 if !Valid(b) { 358 t.Error("invalid JSON representation") 359 } 360 361 if !bytes.Equal(a, b) { 362 t.Error("JSON representations mismatch") 363 t.Log("expected:", string(a)) 364 t.Log("found: ", string(b)) 365 } 366 367 dec := NewDecoder(bytes.NewBuffer(b)) 368 369 if err := dec.Decode(v2.Interface()); err != nil { 370 t.Errorf("%T: %v", err, err) 371 return 372 } 373 374 x1 := v1 375 x2 := v2.Elem().Interface() 376 377 if !reflect.DeepEqual(x1, x2) { 378 t.Error("values mismatch") 379 t.Logf("expected: %#v", x1) 380 t.Logf("found: %#v", x2) 381 } 382 383 if b, err := ioutil.ReadAll(dec.Buffered()); err != nil { 384 t.Error(err) 385 } else if len(b) != 0 { 386 t.Errorf("leftover trailing bytes in the decoder: %q", b) 387 } 388 }) 389 } 390 } 391 392 // TestCodecDuration isolates testing of time.Duration. The stdlib un/marshals 393 // this type as integers whereas this library un/marshals formatted string 394 // values. Therefore, plugging durations into TestCodec would cause fail since 395 // it checks equality on the marshaled strings from the two libraries. 396 func TestCodecDuration(t *testing.T) { 397 t.Skip("Skipping because neilotoole/jsoncolor follows stdlib (encode to int64) rather than segmentj (encode to string)") 398 for _, v1 := range durationTestValues { 399 t.Run(testName(v1), func(t *testing.T) { 400 v2 := newValue(v1) 401 402 // encode using stdlib. (will be an int) 403 std, err := json.MarshalIndent(v1, "", "\t") 404 if err != nil { 405 t.Error(err) 406 return 407 } 408 std = append(std, '\n') 409 410 // decode using our decoder. (reads int to duration) 411 dec := NewDecoder(bytes.NewBuffer([]byte(std))) 412 413 if err := dec.Decode(v2.Interface()); err != nil { 414 t.Errorf("%T: %v", err, err) 415 return 416 } 417 418 x1 := v1 419 x2 := v2.Elem().Interface() 420 421 if !reflect.DeepEqual(x1, x2) { 422 t.Error("values mismatch") 423 t.Logf("expected: %#v", x1) 424 t.Logf("found: %#v", x2) 425 } 426 427 // encoding using our encoder. (writes duration as string) 428 buf := &bytes.Buffer{} 429 enc := NewEncoder(buf) 430 enc.SetIndent("", "\t") 431 432 if err := enc.Encode(v1); err != nil { 433 t.Error(err) 434 return 435 } 436 b := buf.Bytes() 437 438 if !Valid(b) { 439 t.Error("invalid JSON representation") 440 } 441 442 if reflect.DeepEqual(std, b) { 443 t.Error("encoded durations should not match stdlib") 444 t.Logf("got: %s", b) 445 } 446 447 // decode using our decoder. (reads string to duration) 448 dec = NewDecoder(bytes.NewBuffer([]byte(std))) 449 450 if err := dec.Decode(v2.Interface()); err != nil { 451 t.Errorf("%T: %v", err, err) 452 return 453 } 454 455 x1 = v1 456 x2 = v2.Elem().Interface() 457 458 if !reflect.DeepEqual(x1, x2) { 459 t.Error("values mismatch") 460 t.Logf("expected: %#v", x1) 461 t.Logf("found: %#v", x2) 462 } 463 }) 464 } 465 } 466 467 func newValue(model interface{}) reflect.Value { 468 if model == nil { 469 return reflect.New(reflect.TypeOf(&model).Elem()) 470 } 471 return reflect.New(reflect.TypeOf(model)) 472 } 473 474 func BenchmarkMarshal(b *testing.B) { 475 j := make([]byte, 0, 128*1024) 476 477 for _, v := range testValues { 478 b.Run(testName(v), func(b *testing.B) { 479 if marshal == nil { 480 return 481 } 482 483 for i := 0; i != b.N; i++ { 484 j, _ = marshal(j[:0], v) 485 } 486 487 b.SetBytes(int64(len(j))) 488 }) 489 } 490 } 491 492 func BenchmarkUnmarshal(b *testing.B) { 493 for _, v := range testValues { 494 b.Run(testName(v), func(b *testing.B) { 495 if unmarshal == nil { 496 return 497 } 498 499 x := v 500 if d, ok := x.(time.Duration); ok { 501 x = duration(d) 502 } 503 504 j, _ := json.Marshal(x) 505 x = newValue(v).Interface() 506 507 for i := 0; i != b.N; i++ { 508 unmarshal(j, x) 509 } 510 511 b.SetBytes(int64(len(j))) 512 }) 513 } 514 } 515 516 type buffer struct{ data []byte } 517 518 func (buf *buffer) Write(b []byte) (int, error) { 519 buf.data = append(buf.data, b...) 520 return len(b), nil 521 } 522 523 func (buf *buffer) WriteString(s string) (int, error) { 524 buf.data = append(buf.data, s...) 525 return len(s), nil 526 } 527 528 type jsonValue struct { 529 x int32 530 y int32 531 } 532 533 func (v jsonValue) MarshalJSON() ([]byte, error) { 534 return Marshal([2]int32{v.x, v.y}) 535 } 536 537 func (v *jsonValue) UnmarshalJSON(b []byte) error { 538 var a [2]int32 539 err := Unmarshal(b, &a) 540 v.x = a[0] 541 v.y = a[1] 542 return err 543 } 544 545 type textValue struct { 546 x int32 547 y int32 548 } 549 550 func (v textValue) MarshalText() ([]byte, error) { 551 return []byte(fmt.Sprintf("(%d,%d)", v.x, v.y)), nil 552 } 553 554 func (v *textValue) UnmarshalText(b []byte) error { 555 _, err := fmt.Sscanf(string(b), "(%d,%d)", &v.x, &v.y) 556 return err 557 } 558 559 type duration time.Duration 560 561 func (d duration) MarshalJSON() ([]byte, error) { 562 return []byte(`"` + time.Duration(d).String() + `"`), nil 563 } 564 565 func (d *duration) UnmarshalJSON(b []byte) error { 566 var s string 567 if err := json.Unmarshal(b, &s); err != nil { 568 return err 569 } 570 x, err := time.ParseDuration(s) 571 *d = duration(x) 572 return err 573 } 574 575 var ( 576 _ Marshaler = jsonValue{} 577 _ Marshaler = duration(0) 578 579 _ encoding.TextMarshaler = textValue{} 580 581 _ Unmarshaler = (*jsonValue)(nil) 582 _ Unmarshaler = (*duration)(nil) 583 584 _ encoding.TextUnmarshaler = (*textValue)(nil) 585 ) 586 587 func TestDecodeStructFieldCaseInsensitive(t *testing.T) { 588 b := []byte(`{ "type": "changed" }`) 589 s := struct { 590 Type string 591 }{"unchanged"} 592 593 if err := Unmarshal(b, &s); err != nil { 594 t.Error(err) 595 } 596 597 if s.Type != "changed" { 598 t.Error("s.Type: expected to be changed but found", s.Type) 599 } 600 } 601 602 func TestDecodeLines(t *testing.T) { 603 tests := []struct { 604 desc string 605 reader io.Reader 606 expectCount int 607 }{ 608 // simple 609 610 { 611 desc: "bare object", 612 reader: strings.NewReader("{\"Good\":true}"), 613 expectCount: 1, 614 }, 615 { 616 desc: "multiple objects on one line", 617 reader: strings.NewReader("{\"Good\":true}{\"Good\":true}\n"), 618 expectCount: 2, 619 }, 620 { 621 desc: "object spanning multiple lines", 622 reader: strings.NewReader("{\n\"Good\":true\n}\n"), 623 expectCount: 1, 624 }, 625 626 // whitespace handling 627 628 { 629 desc: "trailing newline", 630 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n"), 631 expectCount: 2, 632 }, 633 { 634 desc: "multiple trailing newlines", 635 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n\n"), 636 expectCount: 2, 637 }, 638 { 639 desc: "blank lines", 640 reader: strings.NewReader("{\"Good\":true}\n\n{\"Good\":true}"), 641 expectCount: 2, 642 }, 643 { 644 desc: "no trailing newline", 645 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}"), 646 expectCount: 2, 647 }, 648 { 649 desc: "leading whitespace", 650 reader: strings.NewReader(" {\"Good\":true}\n\t{\"Good\":true}"), 651 expectCount: 2, 652 }, 653 654 // multiple reads 655 656 { 657 desc: "one object, multiple reads", 658 reader: io.MultiReader( 659 strings.NewReader("{"), 660 strings.NewReader("\"Good\": true"), 661 strings.NewReader("}\n"), 662 ), 663 expectCount: 1, 664 }, 665 666 // EOF reads 667 668 { 669 desc: "one object + EOF", 670 reader: &eofReader{"{\"Good\":true}\n"}, 671 expectCount: 1, 672 }, 673 { 674 desc: "leading whitespace + EOF", 675 reader: &eofReader{"\n{\"Good\":true}\n"}, 676 expectCount: 1, 677 }, 678 { 679 desc: "multiple objects + EOF", 680 reader: &eofReader{"{\"Good\":true}\n{\"Good\":true}\n"}, 681 expectCount: 2, 682 }, 683 { 684 desc: "one object + multiple reads + EOF", 685 reader: io.MultiReader( 686 strings.NewReader("{"), 687 strings.NewReader(" \"Good\": true"), 688 &eofReader{"}\n"}, 689 ), 690 expectCount: 1, 691 }, 692 { 693 desc: "multiple objects + multiple reads + EOF", 694 reader: io.MultiReader( 695 strings.NewReader("{"), 696 strings.NewReader(" \"Good\": true}{\"Good\": true}"), 697 &eofReader{"\n"}, 698 ), 699 expectCount: 2, 700 }, 701 702 { 703 // the 2nd object should be discarded, as 42 cannot be cast to bool 704 desc: "unmarshal error while decoding", 705 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n{\"Good\":true}\n"), 706 expectCount: 2, 707 }, 708 { 709 // the 2nd object should be discarded, as 42 cannot be cast to bool 710 desc: "unmarshal error while decoding last object", 711 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n"), 712 expectCount: 1, 713 }, 714 } 715 716 type obj struct { 717 Good bool 718 } 719 720 for _, test := range tests { 721 t.Run(test.desc, func(t *testing.T) { 722 d := NewDecoder(test.reader) 723 var count int 724 var err error 725 for { 726 var o obj 727 err = d.Decode(&o) 728 if err != nil { 729 if err == io.EOF { 730 break 731 } 732 733 switch err.(type) { 734 case *SyntaxError, *UnmarshalTypeError: 735 t.Log("unmarshal error", err) 736 continue 737 } 738 739 t.Error("decode error", err) 740 break 741 } 742 if !o.Good { 743 t.Errorf("object was not unmarshaled correctly: %#v", o) 744 } 745 count++ 746 } 747 748 if err != nil && err != io.EOF { 749 t.Error(err) 750 } 751 752 if count != test.expectCount { 753 t.Errorf("expected %d objects, got %d", test.expectCount, count) 754 } 755 }) 756 } 757 } 758 759 // eofReader is a simple io.Reader that reads its full contents _and_ returns 760 // and EOF in the first call. Subsequent Read calls only return EOF. 761 type eofReader struct { 762 s string 763 } 764 765 func (r *eofReader) Read(p []byte) (n int, err error) { 766 n = copy(p, r.s) 767 r.s = r.s[n:] 768 if r.s == "" { 769 err = io.EOF 770 } 771 return 772 } 773 774 func TestDontMatchCaseIncensitiveStructFields(t *testing.T) { 775 b := []byte(`{ "type": "changed" }`) 776 s := struct { 777 Type string 778 }{"unchanged"} 779 780 if _, err := Parse(b, &s, DontMatchCaseInsensitiveStructFields); err != nil { 781 t.Error(err) 782 } 783 784 if s.Type != "unchanged" { 785 t.Error("s.Type: expected to be unchanged but found", s.Type) 786 } 787 } 788 789 func TestMarshalFuzzBugs(t *testing.T) { 790 tests := []struct { 791 value interface{} 792 output string 793 }{ 794 { // html sequences are escaped even in RawMessage 795 value: struct { 796 P RawMessage 797 }{P: RawMessage(`"<"`)}, 798 output: "{\"P\":\"\\u003c\"}", 799 }, 800 { // raw message output is compacted 801 value: struct { 802 P RawMessage 803 }{P: RawMessage(`{"" :{}}`)}, 804 output: "{\"P\":{\"\":{}}}", 805 }, 806 } 807 808 for _, test := range tests { 809 t.Run("", func(t *testing.T) { 810 b, err := Marshal(test.value) 811 if err != nil { 812 t.Fatal(err) 813 } 814 815 if string(b) != test.output { 816 t.Error("values mismatch") 817 t.Logf("expected: %#v", test.output) 818 t.Logf("found: %#v", string(b)) 819 } 820 }) 821 } 822 } 823 824 func TestUnmarshalFuzzBugs(t *testing.T) { 825 tests := []struct { 826 input string 827 value interface{} 828 }{ 829 { // non-UTF8 sequences must be converted to the utf8.RuneError character. 830 input: "[\"00000\xef\"]", 831 value: []interface{}{"00000�"}, 832 }, 833 { // UTF16 surrogate followed by null character 834 input: "[\"\\ud800\\u0000\"]", 835 value: []interface{}{"�\x00"}, 836 }, 837 { // UTF16 surrogate followed by ascii character 838 input: "[\"\\uDF00\\u000e\"]", 839 value: []interface{}{"�\x0e"}, 840 }, 841 { // UTF16 surrogate followed by unicode character 842 input: "[[\"\\uDF00\\u0800\"]]", 843 value: []interface{}{[]interface{}{"�ࠀ"}}, 844 }, 845 { // invalid UTF16 surrogate sequenced followed by a valid UTF16 surrogate sequence 846 input: "[\"\\udf00\\udb00\\udf00\"]", 847 value: []interface{}{"�\U000d0300"}, 848 }, 849 { // decode single-element slice into []byte field 850 input: "{\"f\":[0],\"0\":[0]}", 851 value: struct{ F []byte }{F: []byte{0}}, 852 }, 853 { // decode multi-element slice into []byte field 854 input: "{\"F\":[3,1,1,1,9,9]}", 855 value: struct{ F []byte }{F: []byte{3, 1, 1, 1, 9, 9}}, 856 }, 857 { // decode string with escape sequence into []byte field 858 input: "{\"F\":\"0p00\\r\"}", 859 value: struct{ F []byte }{F: []byte("ҝ4")}, 860 }, 861 { // decode unicode code points which fold into ascii characters 862 input: "{\"ſ\":\"8\"}", 863 value: struct { 864 S int `json:",string"` 865 }{S: 8}, 866 }, 867 { // decode unicode code points which don't fold into ascii characters 868 input: "{\"İ\":\"\"}", 869 value: struct{ I map[string]string }{I: nil}, 870 }, 871 { // override pointer-to-pointer field clears the inner pointer only 872 input: "{\"o\":0,\"o\":null}", 873 value: struct{ O **int }{O: new(*int)}, 874 }, 875 { // subsequent occurrences of a map field retain keys previously loaded 876 input: "{\"i\":{\"\":null},\"i\":{}}", 877 value: struct{ I map[string]string }{I: map[string]string{"": ""}}, 878 }, 879 { // an empty string is an invalid JSON input 880 input: "", 881 }, 882 { // ASCII character below 0x20 are invalid JSON input 883 input: "[\"\b\"]", 884 }, 885 { // random byte before any value 886 input: "\xad", 887 }, 888 { // cloud be the beginning of a false value but not 889 input: "f", 890 value: false, 891 }, 892 { // random ASCII character 893 input: "}", 894 value: []interface{}{}, 895 }, 896 { // random byte after valid JSON, decoded to a nil type 897 input: "0\x93", 898 }, 899 { // random byte after valid JSON, decoded to a int type 900 input: "0\x93", 901 value: 0, 902 }, 903 { // random byte after valid JSON, decoded to a slice type 904 input: "0\x93", 905 value: []interface{}{}, 906 }, 907 { // decode integer into slice 908 input: "0", 909 value: []interface{}{}, 910 }, 911 { // decode integer with trailing space into slice 912 input: "0\t", 913 value: []interface{}{}, 914 }, 915 { // decode integer with leading random bytes into slice 916 input: "\b0", 917 value: []interface{}{}, 918 }, 919 { // decode string into slice followed by number 920 input: "\"\"0", 921 value: []interface{}{}, 922 }, 923 { // decode what looks like an object followed by a number into a string 924 input: "{0", 925 value: "", 926 }, 927 { // decode what looks like an object followed by a number into a map 928 input: "{0", 929 value: map[string]string{}, 930 }, 931 { // decode string into string with trailing random byte 932 input: "\"\"\f", 933 value: "", 934 }, 935 { // decode weird number value into nil 936 input: "-00", 937 }, 938 { // decode an invalid escaped sequence 939 input: "\"\\0\"", 940 value: "", 941 }, 942 { // decode what looks like an array followed by a number into a slice 943 input: "[9E600", 944 value: []interface{}{}, 945 }, 946 { // decode a number which is too large to fit in a float64 947 input: "[1e900]", 948 value: []interface{}{}, 949 }, 950 { // many nested arrays openings 951 input: "[[[[[[", 952 value: []interface{}{}, 953 }, 954 { // decode a map with value type mismatch and missing closing character 955 input: "{\"\":0", 956 value: map[string]string{}, 957 }, 958 { // decode a struct with value type mismatch and missing closing character 959 input: "{\"E\":\"\"", 960 value: struct{ E uint8 }{}, 961 }, 962 { // decode a map with value type mismatch 963 input: "{\"\":0}", 964 value: map[string]string{}, 965 }, 966 { // decode number with exponent into integer field 967 input: "{\"e\":0e0}", 968 value: struct{ E uint8 }{}, 969 }, 970 { // decode invalid integer representation into integer field 971 input: "{\"e\":00}", 972 value: struct{ E uint8 }{}, 973 }, 974 { // decode unterminated array into byte slice 975 input: "{\"F\":[", 976 value: struct{ F []byte }{}, 977 }, 978 { // attempt to decode string into in 979 input: "{\"S\":\"\"}", 980 value: struct { 981 S int `json:",string"` 982 }{}, 983 }, 984 { // decode object with null key into map 985 input: "{null:0}", 986 value: map[string]interface{}{}, 987 }, 988 { // decode unquoted integer into struct field with string tag 989 input: "{\"S\":0}", 990 value: struct { 991 S int `json:",string"` 992 }{}, 993 }, 994 { // invalid base64 content when decoding string into byte slice 995 input: "{\"F\":\"0\"}", 996 value: struct{ F []byte }{}, 997 }, 998 { // decode an object with a "null" string as key 999 input: "{\"null\":null}", 1000 value: struct { 1001 S int `json:",string"` 1002 }{}, 1003 }, 1004 { // decode an invalid floating point number representation into an integer field with string tag 1005 input: "{\"s\":8e800}", 1006 value: struct { 1007 S int `json:",string"` 1008 }{}, 1009 }, 1010 { // decode a string with leading zeroes into an integer field with string tag 1011 input: "{\"S\":\"00\"}", 1012 value: struct { 1013 S int `json:",string"` 1014 }{}, 1015 }, 1016 { // decode a string with invalid leading sign and zeroes into an integer field with string tag 1017 input: "{\"S\":\"+00\"}", 1018 value: struct { 1019 S int `json:",string"` 1020 }{}, 1021 }, 1022 { // decode a string with valid leading sign and zeroes into an integer field with string tag 1023 input: "{\"S\":\"-00\"}", 1024 value: struct { 1025 S int `json:",string"` 1026 }{}, 1027 }, 1028 { // decode non-ascii string into integer field with string tag 1029 input: "{\"ſ\":\"\xbf\"}", 1030 value: struct { 1031 S int `json:",string"` 1032 }{}, 1033 }, 1034 { // decode a valid floating point number representation into an integer field with string tag 1035 input: "{\"S\":0.0}", 1036 value: struct { 1037 S int `json:",string"` 1038 }{}, 1039 }, 1040 { // decode string with invalid leading sign to integer field with string tag 1041 input: "{\"S\":\"+0\"}", 1042 value: struct { 1043 S int `json:",string"` 1044 }{}, 1045 }, 1046 { // decode string with valid leading sign to integer field with string tag 1047 input: "{\"S\":\"-0\"}", 1048 value: struct { 1049 S int `json:",string"` 1050 }{}, 1051 }, 1052 { // decode string with object representation to integer field with string tag 1053 input: "{\"s\":{}}", 1054 value: struct { 1055 S int `json:",string"` 1056 }{}, 1057 }, 1058 { // decoding integer with leading zeroes 1059 input: "{\"o\":00}", 1060 value: struct{ O **int }{}, 1061 }, 1062 { // codeding string with invalid float representation into integer field with string tag 1063 input: "{\"s\":\"0.\"}", 1064 value: struct { 1065 S int `json:",string"` 1066 }{}, 1067 }, 1068 { // malformed negative integer in object value 1069 input: "{\"N\":-00}", 1070 value: struct{ N *int }{}, 1071 }, 1072 { // integer overflow 1073 input: "{\"a\":9223372036854775808}", 1074 value: struct { 1075 A int `json:",omitempty"` 1076 }{}, 1077 }, 1078 { // decode string with number followed by random byte into integer field with string tag 1079 input: "{\"s\":\"0]\"}", 1080 value: struct { 1081 S int `json:",string"` 1082 }{}, 1083 }, 1084 { // decode object into integer field 1085 input: "{\"n\":{}}", 1086 value: struct{ N *int }{}, 1087 }, 1088 { // decode negative integer into unsigned type 1089 input: "{\"E\":-0}", 1090 value: struct{ E uint8 }{}, 1091 }, 1092 { // decode string with number followed by random byte into integer field with string tag 1093 input: "{\"s\":\"03�\"}", 1094 value: struct { 1095 S int `json:",string"` 1096 }{}, 1097 }, 1098 { // decode string with leading zeroes into integer field with string tag 1099 input: "{\"s\":\"03\"}", 1100 value: struct { 1101 S int `json:",string"` 1102 }{S: 3}, 1103 }, 1104 { // decode string containing what looks like an object into integer field with string tag 1105 input: "{\"S\":\"{}\"}", 1106 value: struct { 1107 S int `json:",string"` 1108 }{}, 1109 }, 1110 { // decode an empty string followed by the same field with a null value into a byte slice 1111 input: "{\"F\":\"\",\"F\":null}", 1112 value: struct{ F []byte }{}, 1113 }, 1114 { // decode string containing a float into an integer field with string tag 1115 input: "{\"S\":\"0e0\"}", 1116 value: struct { 1117 S int `json:",string"` 1118 }{}, 1119 }, 1120 { // decode string with negative sign into a an integer field with string tag 1121 input: "{\"s\":\"-\"}", 1122 value: struct { 1123 S int `json:",string"` 1124 }{}, 1125 }, 1126 { // decode string with positive sign into a an integer field with string tag 1127 input: "{\"s\":\"+\"}", 1128 value: struct { 1129 S int `json:",string"` 1130 }{}, 1131 }, 1132 { // decode an integer into a json unmarshaler 1133 input: "{\"q\":0}", 1134 value: struct { 1135 Q testMarshaller 1136 }{}, 1137 }, 1138 // This test fails because it appears that the encoding/json package 1139 // will decode "q" before "s", so it returns an error about "q" being of 1140 // the wrong type while this package will prase object keys in the order 1141 // that they appear in the JSON input, so it detects the error from "s" 1142 // first. 1143 // 1144 //{ 1145 // input: "{\"s\":0,\"q\":0}", 1146 // value: struct { 1147 // Q testMarshaller 1148 // S int `json:",string"` 1149 // }{}, 1150 //}, 1151 } 1152 1153 for _, test := range tests { 1154 t.Run("", func(t *testing.T) { 1155 var ptr1 interface{} 1156 var ptr2 interface{} 1157 1158 if test.value != nil { 1159 ptr1 = reflect.New(reflect.TypeOf(test.value)).Interface() 1160 ptr2 = reflect.New(reflect.TypeOf(test.value)).Interface() 1161 } 1162 1163 err1 := json.Unmarshal([]byte(test.input), ptr1) 1164 err2 := Unmarshal([]byte(test.input), ptr2) 1165 1166 if reflect.TypeOf(err1) != reflect.TypeOf(err2) { 1167 t.Error("errors mismatch") 1168 t.Logf("expected: %T: %v", err1, err1) 1169 t.Logf("found: %T: %v", err2, err2) 1170 } else if err1 == nil && test.value != nil { 1171 if value := reflect.ValueOf(ptr2).Elem().Interface(); !reflect.DeepEqual(test.value, value) { 1172 t.Error("values mismatch") 1173 t.Logf("expected: %#v", test.value) 1174 t.Logf("found: %#v", value) 1175 } 1176 } 1177 }) 1178 } 1179 } 1180 1181 func BenchmarkEasyjsonUnmarshalSmallStruct(b *testing.B) { 1182 type Hashtag struct { 1183 Indices []int `json:"indices"` 1184 Text string `json:"text"` 1185 } 1186 1187 //easyjson:json 1188 type Entities struct { 1189 Hashtags []Hashtag `json:"hashtags"` 1190 Urls []*string `json:"urls"` 1191 UserMentions []*string `json:"user_mentions"` 1192 } 1193 1194 json := []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`) 1195 1196 for i := 0; i < b.N; i++ { 1197 var value Entities 1198 if err := Unmarshal(json, &value); err != nil { 1199 b.Fatal(err) 1200 } 1201 } 1202 } 1203 1204 type testMarshaller struct { 1205 v string 1206 } 1207 1208 func (m *testMarshaller) MarshalJSON() ([]byte, error) { 1209 return Marshal(m.v) 1210 } 1211 1212 func (m *testMarshaller) UnmarshalJSON(data []byte) error { 1213 return Unmarshal(data, &m.v) 1214 } 1215 1216 func TestGithubIssue11(t *testing.T) { 1217 // https://github.com/segmentio/encoding/issues/11 1218 v := struct{ F float64 }{ 1219 F: math.NaN(), 1220 } 1221 1222 _, err := Marshal(v) 1223 if err == nil { 1224 t.Error("no error returned when marshalling NaN value") 1225 } else if s := err.Error(); !strings.Contains(s, "NaN") { 1226 t.Error("error returned when marshalling NaN value does not mention 'NaN':", s) 1227 } else { 1228 t.Log(s) 1229 } 1230 } 1231 1232 type Issue13 struct { 1233 Stringer fmt.Stringer 1234 Field int `json:"MyInt"` 1235 } 1236 1237 type S string 1238 1239 func (s S) String() string { return string(s) } 1240 1241 func TestGithubIssue13(t *testing.T) { 1242 // https://github.com/segmentio/encoding/issues/13 1243 v := Issue13{} 1244 1245 b, err := Marshal(v) 1246 if err != nil { 1247 t.Error("unexpected errror:", err) 1248 } else { 1249 t.Log(string(b)) 1250 } 1251 1252 v = Issue13{Stringer: S("")} 1253 if err := Unmarshal([]byte(`{"Stringer":null}`), &v); err != nil { 1254 t.Error("unexpected error:", err) 1255 } 1256 if v.Stringer != nil { 1257 t.Error("Stringer field was not overwritten") 1258 } 1259 1260 v = Issue13{} 1261 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1262 t.Error("expected error but decoding string value into nil fmt.Stringer but got <nil>") 1263 } 1264 1265 v = Issue13{Stringer: S("")} 1266 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1267 t.Error("expected error but decoding string value into non-pointer fmt.Stringer but got <nil>") 1268 } 1269 1270 s := S("") 1271 v = Issue13{Stringer: &s} 1272 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err != nil { 1273 t.Error("unexpected error decoding string value into pointer fmt.Stringer:", err) 1274 } 1275 } 1276 1277 func TestGithubIssue15(t *testing.T) { 1278 // https://github.com/segmentio/encoding/issues/15 1279 tests := []struct { 1280 m interface{} 1281 s string 1282 }{ 1283 { 1284 m: map[uint]bool{1: true, 123: true, 333: true, 42: true}, 1285 s: `{"1":true,"123":true,"333":true,"42":true}`, 1286 }, 1287 { 1288 m: map[int]bool{-1: true, -123: true, 333: true, 42: true}, 1289 s: `{"-1":true,"-123":true,"333":true,"42":true}`, 1290 }, 1291 } 1292 1293 for _, test := range tests { 1294 b, _ := Marshal(test.m) 1295 1296 if string(b) != test.s { 1297 t.Error("map with integer keys must be ordered by their string representation, got", string(b)) 1298 } 1299 1300 } 1301 } 1302 1303 type sliceA []byte 1304 1305 func (sliceA) MarshalJSON() ([]byte, error) { 1306 return []byte(`"A"`), nil 1307 } 1308 1309 type sliceB []byte 1310 1311 func (sliceB) MarshalText() ([]byte, error) { 1312 return []byte("B"), nil 1313 } 1314 1315 type mapA map[string]string 1316 1317 func (mapA) MarshalJSON() ([]byte, error) { 1318 return []byte(`"A"`), nil 1319 } 1320 1321 type mapB map[string]string 1322 1323 func (mapB) MarshalText() ([]byte, error) { 1324 return []byte("B"), nil 1325 } 1326 1327 type intPtrA int 1328 1329 func (*intPtrA) MarshalJSON() ([]byte, error) { 1330 return []byte(`"A"`), nil 1331 } 1332 1333 type intPtrB int 1334 1335 func (*intPtrB) MarshalText() ([]byte, error) { 1336 return []byte("B"), nil 1337 } 1338 1339 type ( 1340 structA struct{ I intPtrA } 1341 structB struct{ I intPtrB } 1342 structC struct{ M Marshaler } 1343 structD struct{ M encoding.TextMarshaler } 1344 ) 1345 1346 func TestGithubIssue16(t *testing.T) { 1347 // https://github.com/segmentio/encoding/issues/16 1348 tests := []struct { 1349 value interface{} 1350 output string 1351 }{ 1352 {value: sliceA(nil), output: `"A"`}, 1353 {value: sliceB(nil), output: `"B"`}, 1354 {value: mapA(nil), output: `"A"`}, 1355 {value: mapB(nil), output: `"B"`}, 1356 {value: intPtrA(1), output: `1`}, 1357 {value: intPtrB(2), output: `2`}, 1358 {value: new(intPtrA), output: `"A"`}, 1359 {value: new(intPtrB), output: `"B"`}, 1360 {value: (*intPtrA)(nil), output: `null`}, 1361 {value: (*intPtrB)(nil), output: `null`}, 1362 {value: structA{I: 1}, output: `{"I":1}`}, 1363 {value: structB{I: 2}, output: `{"I":2}`}, 1364 {value: structC{}, output: `{"M":null}`}, 1365 {value: structD{}, output: `{"M":null}`}, 1366 {value: &structA{I: 1}, output: `{"I":"A"}`}, 1367 {value: &structB{I: 2}, output: `{"I":"B"}`}, 1368 {value: &structC{}, output: `{"M":null}`}, 1369 {value: &structD{}, output: `{"M":null}`}, 1370 } 1371 1372 for _, test := range tests { 1373 t.Run(fmt.Sprintf("%T", test.value), func(t *testing.T) { 1374 if b, _ := Marshal(test.value); string(b) != test.output { 1375 t.Errorf(`%s != %s`, string(b), test.output) 1376 } 1377 }) 1378 } 1379 } 1380 1381 func TestDecoderInputOffset(t *testing.T) { 1382 checkOffset := func(o, expected int64) { 1383 if o != expected { 1384 t.Error("unexpected input offset", o, expected) 1385 } 1386 } 1387 1388 b := []byte(`{"userId": "blah"}{"userId": "blah"} 1389 {"userId": "blah"}{"num": 0}`) 1390 d := NewDecoder(bytes.NewReader(b)) 1391 1392 var expected int64 1393 checkOffset(d.InputOffset(), expected) 1394 1395 var a struct { 1396 UserId string `json:"userId"` 1397 } 1398 1399 if err := d.Decode(&a); err != nil { 1400 t.Error("unexpected decode error", err) 1401 } 1402 expected = int64(18) 1403 checkOffset(d.InputOffset(), expected) 1404 1405 if err := d.Decode(&a); err != nil { 1406 t.Error("unexpected decode error", err) 1407 } 1408 expected = int64(38) 1409 checkOffset(d.InputOffset(), expected) 1410 1411 if err := d.Decode(&a); err != nil { 1412 t.Error("unexpected decode error", err) 1413 } 1414 expected = int64(56) 1415 checkOffset(d.InputOffset(), expected) 1416 1417 var z struct { 1418 Num int64 `json:"num"` 1419 } 1420 if err := d.Decode(&z); err != nil { 1421 t.Error("unexpected decode error", err) 1422 } 1423 expected = int64(66) 1424 checkOffset(d.InputOffset(), expected) 1425 } 1426 1427 func TestGithubIssue18(t *testing.T) { 1428 // https://github.com/segmentio/encoding/issues/18 1429 b := []byte(`{ 1430 "userId": "blah", 1431 }`) 1432 1433 d := NewDecoder(bytes.NewReader(b)) 1434 1435 var a struct { 1436 UserId string `json:"userId"` 1437 } 1438 switch err := d.Decode(&a).(type) { 1439 case *SyntaxError: 1440 default: 1441 t.Error("expected syntax error but found:", err) 1442 } 1443 1444 for i := 1; i <= 18; i++ { // up to the invalid ',' character 1445 d := NewDecoder(bytes.NewReader(b[:i])) // cut somewhere in the middle 1446 switch err := d.Decode(&a); err { 1447 case io.ErrUnexpectedEOF: 1448 default: 1449 t.Error("expected 'unexpected EOF' error but found:", err) 1450 } 1451 } 1452 } 1453 1454 func TestGithubIssue23(t *testing.T) { 1455 t.Run("marshal-1", func(t *testing.T) { 1456 type d struct{ S map[string]string } 1457 1458 b, _ := Marshal(map[string]d{"1": {S: map[string]string{"2": "3"}}}) 1459 if string(b) != `{"1":{"S":{"2":"3"}}}` { 1460 t.Error(string(b)) 1461 } 1462 }) 1463 1464 t.Run("marshal-2", func(t *testing.T) { 1465 type testInner struct { 1466 InnerMap map[string]string `json:"inner_map"` 1467 } 1468 1469 type testOuter struct { 1470 OuterMap map[string]testInner `json:"outer_map"` 1471 } 1472 1473 b, _ := Marshal(testOuter{ 1474 OuterMap: map[string]testInner{ 1475 "outer": { 1476 InnerMap: map[string]string{"inner": "value"}, 1477 }, 1478 }, 1479 }) 1480 1481 if string(b) != `{"outer_map":{"outer":{"inner_map":{"inner":"value"}}}}` { 1482 t.Error(string(b)) 1483 } 1484 }) 1485 1486 t.Run("marshal-3", func(t *testing.T) { 1487 type A struct{ A map[string]string } 1488 type B struct{ B map[string]A } 1489 type C struct{ C map[string]B } 1490 1491 b, _ := Marshal(C{ 1492 C: map[string]B{ 1493 "1": { 1494 B: map[string]A{ 1495 "2": { 1496 A: map[string]string{"3": "!"}, 1497 }, 1498 }, 1499 }, 1500 }, 1501 }) 1502 1503 if string(b) != `{"C":{"1":{"B":{"2":{"A":{"3":"!"}}}}}}` { 1504 t.Error(string(b)) 1505 } 1506 }) 1507 1508 t.Run("unmarshal-1", func(t *testing.T) { 1509 var d struct{ S map[string]string } 1510 1511 if err := Unmarshal([]byte(`{"1":{"S":{"2":"3"}}}`), &d); err != nil { 1512 t.Error(err) 1513 } 1514 }) 1515 } 1516 1517 func TestGithubIssue26(t *testing.T) { 1518 type interfaceType interface{} 1519 1520 var value interfaceType 1521 data := []byte(`{}`) 1522 1523 if err := Unmarshal(data, &value); err != nil { 1524 t.Error(err) 1525 } 1526 } 1527 1528 func TestGithubIssue28(t *testing.T) { 1529 type A struct { 1530 Err error `json:"err"` 1531 } 1532 1533 if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil { 1534 t.Error(err) 1535 } else if string(b) != `{"err":{}}` { 1536 t.Error(string(b)) 1537 } 1538 } 1539 1540 func TestSetTrustRawMessage(t *testing.T) { 1541 buf := &bytes.Buffer{} 1542 enc := NewEncoder(buf) 1543 enc.SetTrustRawMessage(true) 1544 1545 // "Good" values are encoded in the regular way 1546 m := map[string]json.RawMessage{ 1547 "k": json.RawMessage(`"value"`), 1548 } 1549 if err := enc.Encode(m); err != nil { 1550 t.Error(err) 1551 } 1552 1553 b := buf.Bytes() 1554 exp := []byte(`{"k":"value"}`) 1555 exp = append(exp, '\n') 1556 if bytes.Compare(exp, b) != 0 { 1557 t.Error( 1558 "unexpected encoding:", 1559 "expected", exp, 1560 "got", b, 1561 ) 1562 } 1563 1564 // "Bad" values are encoded without checking and throwing an error 1565 buf.Reset() 1566 m = map[string]json.RawMessage{ 1567 "k": json.RawMessage(`bad"value`), 1568 } 1569 if err := enc.Encode(m); err != nil { 1570 t.Error(err) 1571 } 1572 1573 b = buf.Bytes() 1574 exp = []byte(`{"k":bad"value}`) 1575 exp = append(exp, '\n') 1576 if bytes.Compare(exp, b) != 0 { 1577 t.Error( 1578 "unexpected encoding:", 1579 "expected", exp, 1580 "got", b, 1581 ) 1582 } 1583 }