github.com/neilotoole/jsoncolor@v0.6.0/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 609 // simple 610 611 { 612 desc: "bare object", 613 reader: strings.NewReader("{\"Good\":true}"), 614 expectCount: 1, 615 }, 616 { 617 desc: "multiple objects on one line", 618 reader: strings.NewReader("{\"Good\":true}{\"Good\":true}\n"), 619 expectCount: 2, 620 }, 621 { 622 desc: "object spanning multiple lines", 623 reader: strings.NewReader("{\n\"Good\":true\n}\n"), 624 expectCount: 1, 625 }, 626 627 // whitespace handling 628 629 { 630 desc: "trailing newline", 631 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n"), 632 expectCount: 2, 633 }, 634 { 635 desc: "multiple trailing newlines", 636 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n\n"), 637 expectCount: 2, 638 }, 639 { 640 desc: "blank lines", 641 reader: strings.NewReader("{\"Good\":true}\n\n{\"Good\":true}"), 642 expectCount: 2, 643 }, 644 { 645 desc: "no trailing newline", 646 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}"), 647 expectCount: 2, 648 }, 649 { 650 desc: "leading whitespace", 651 reader: strings.NewReader(" {\"Good\":true}\n\t{\"Good\":true}"), 652 expectCount: 2, 653 }, 654 655 // multiple reads 656 657 { 658 desc: "one object, multiple reads", 659 reader: io.MultiReader( 660 strings.NewReader("{"), 661 strings.NewReader("\"Good\": true"), 662 strings.NewReader("}\n"), 663 ), 664 expectCount: 1, 665 }, 666 667 // EOF reads 668 669 { 670 desc: "one object + EOF", 671 reader: &eofReader{"{\"Good\":true}\n"}, 672 expectCount: 1, 673 }, 674 { 675 desc: "leading whitespace + EOF", 676 reader: &eofReader{"\n{\"Good\":true}\n"}, 677 expectCount: 1, 678 }, 679 { 680 desc: "multiple objects + EOF", 681 reader: &eofReader{"{\"Good\":true}\n{\"Good\":true}\n"}, 682 expectCount: 2, 683 }, 684 { 685 desc: "one object + multiple reads + EOF", 686 reader: io.MultiReader( 687 strings.NewReader("{"), 688 strings.NewReader(" \"Good\": true"), 689 &eofReader{"}\n"}, 690 ), 691 expectCount: 1, 692 }, 693 { 694 desc: "multiple objects + multiple reads + EOF", 695 reader: io.MultiReader( 696 strings.NewReader("{"), 697 strings.NewReader(" \"Good\": true}{\"Good\": true}"), 698 &eofReader{"\n"}, 699 ), 700 expectCount: 2, 701 }, 702 703 { 704 // the 2nd object should be discarded, as 42 cannot be cast to bool 705 desc: "unmarshal error while decoding", 706 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n{\"Good\":true}\n"), 707 expectCount: 2, 708 }, 709 { 710 // the 2nd object should be discarded, as 42 cannot be cast to bool 711 desc: "unmarshal error while decoding last object", 712 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n"), 713 expectCount: 1, 714 }, 715 } 716 717 type obj struct { 718 Good bool 719 } 720 721 for _, test := range tests { 722 t.Run(test.desc, func(t *testing.T) { 723 d := NewDecoder(test.reader) 724 var count int 725 var err error 726 for { 727 var o obj 728 err = d.Decode(&o) 729 if err != nil { 730 if err == io.EOF { 731 break 732 } 733 734 switch err.(type) { 735 case *SyntaxError, *UnmarshalTypeError, *UnmarshalFieldError: 736 t.Log("unmarshal error", err) 737 continue 738 } 739 740 t.Error("decode error", err) 741 break 742 } 743 if !o.Good { 744 t.Errorf("object was not unmarshaled correctly: %#v", o) 745 } 746 count++ 747 } 748 749 if err != nil && err != io.EOF { 750 t.Error(err) 751 } 752 753 if count != test.expectCount { 754 t.Errorf("expected %d objects, got %d", test.expectCount, count) 755 } 756 }) 757 } 758 } 759 760 // eofReader is a simple io.Reader that reads its full contents _and_ returns 761 // and EOF in the first call. Subsequent Read calls only return EOF. 762 type eofReader struct { 763 s string 764 } 765 766 func (r *eofReader) Read(p []byte) (n int, err error) { 767 n = copy(p, r.s) 768 r.s = r.s[n:] 769 if r.s == "" { 770 err = io.EOF 771 } 772 return 773 } 774 775 func TestDontMatchCaseIncensitiveStructFields(t *testing.T) { 776 b := []byte(`{ "type": "changed" }`) 777 s := struct { 778 Type string 779 }{"unchanged"} 780 781 if _, err := Parse(b, &s, DontMatchCaseInsensitiveStructFields); err != nil { 782 t.Error(err) 783 } 784 785 if s.Type != "unchanged" { 786 t.Error("s.Type: expected to be unchanged but found", s.Type) 787 } 788 } 789 790 func TestMarshalFuzzBugs(t *testing.T) { 791 tests := []struct { 792 value interface{} 793 output string 794 }{ 795 { // html sequences are escaped even in RawMessage 796 value: struct { 797 P RawMessage 798 }{P: RawMessage(`"<"`)}, 799 output: "{\"P\":\"\\u003c\"}", 800 }, 801 { // raw message output is compacted 802 value: struct { 803 P RawMessage 804 }{P: RawMessage(`{"" :{}}`)}, 805 output: "{\"P\":{\"\":{}}}", 806 }, 807 } 808 809 for _, test := range tests { 810 t.Run("", func(t *testing.T) { 811 b, err := Marshal(test.value) 812 if err != nil { 813 t.Fatal(err) 814 } 815 816 if string(b) != test.output { 817 t.Error("values mismatch") 818 t.Logf("expected: %#v", test.output) 819 t.Logf("found: %#v", string(b)) 820 } 821 }) 822 } 823 } 824 825 func TestUnmarshalFuzzBugs(t *testing.T) { 826 tests := []struct { 827 input string 828 value interface{} 829 }{ 830 { // non-UTF8 sequences must be converted to the utf8.RuneError character. 831 input: "[\"00000\xef\"]", 832 value: []interface{}{"00000�"}, 833 }, 834 { // UTF16 surrogate followed by null character 835 input: "[\"\\ud800\\u0000\"]", 836 value: []interface{}{"�\x00"}, 837 }, 838 { // UTF16 surrogate followed by ascii character 839 input: "[\"\\uDF00\\u000e\"]", 840 value: []interface{}{"�\x0e"}, 841 }, 842 { // UTF16 surrogate followed by unicode character 843 input: "[[\"\\uDF00\\u0800\"]]", 844 value: []interface{}{[]interface{}{"�ࠀ"}}, 845 }, 846 { // invalid UTF16 surrogate sequenced followed by a valid UTF16 surrogate sequence 847 input: "[\"\\udf00\\udb00\\udf00\"]", 848 value: []interface{}{"�\U000d0300"}, 849 }, 850 { // decode single-element slice into []byte field 851 input: "{\"f\":[0],\"0\":[0]}", 852 value: struct{ F []byte }{F: []byte{0}}, 853 }, 854 { // decode multi-element slice into []byte field 855 input: "{\"F\":[3,1,1,1,9,9]}", 856 value: struct{ F []byte }{F: []byte{3, 1, 1, 1, 9, 9}}, 857 }, 858 { // decode string with escape sequence into []byte field 859 input: "{\"F\":\"0p00\\r\"}", 860 value: struct{ F []byte }{F: []byte("ҝ4")}, 861 }, 862 { // decode unicode code points which fold into ascii characters 863 input: "{\"ſ\":\"8\"}", 864 value: struct { 865 S int `json:",string"` 866 }{S: 8}, 867 }, 868 { // decode unicode code points which don't fold into ascii characters 869 input: "{\"İ\":\"\"}", 870 value: struct{ I map[string]string }{I: nil}, 871 }, 872 { // override pointer-to-pointer field clears the inner pointer only 873 input: "{\"o\":0,\"o\":null}", 874 value: struct{ O **int }{O: new(*int)}, 875 }, 876 { // subsequent occurrences of a map field retain keys previously loaded 877 input: "{\"i\":{\"\":null},\"i\":{}}", 878 value: struct{ I map[string]string }{I: map[string]string{"": ""}}, 879 }, 880 { // an empty string is an invalid JSON input 881 input: "", 882 }, 883 { // ASCII character below 0x20 are invalid JSON input 884 input: "[\"\b\"]", 885 }, 886 { // random byte before any value 887 input: "\xad", 888 }, 889 { // cloud be the beginning of a false value but not 890 input: "f", 891 value: false, 892 }, 893 { // random ASCII character 894 input: "}", 895 value: []interface{}{}, 896 }, 897 { // random byte after valid JSON, decoded to a nil type 898 input: "0\x93", 899 }, 900 { // random byte after valid JSON, decoded to a int type 901 input: "0\x93", 902 value: 0, 903 }, 904 { // random byte after valid JSON, decoded to a slice type 905 input: "0\x93", 906 value: []interface{}{}, 907 }, 908 { // decode integer into slice 909 input: "0", 910 value: []interface{}{}, 911 }, 912 { // decode integer with trailing space into slice 913 input: "0\t", 914 value: []interface{}{}, 915 }, 916 { // decode integer with leading random bytes into slice 917 input: "\b0", 918 value: []interface{}{}, 919 }, 920 { // decode string into slice followed by number 921 input: "\"\"0", 922 value: []interface{}{}, 923 }, 924 { // decode what looks like an object followed by a number into a string 925 input: "{0", 926 value: "", 927 }, 928 { // decode what looks like an object followed by a number into a map 929 input: "{0", 930 value: map[string]string{}, 931 }, 932 { // decode string into string with trailing random byte 933 input: "\"\"\f", 934 value: "", 935 }, 936 { // decode weird number value into nil 937 input: "-00", 938 }, 939 { // decode an invalid escaped sequence 940 input: "\"\\0\"", 941 value: "", 942 }, 943 { // decode what looks like an array followed by a number into a slice 944 input: "[9E600", 945 value: []interface{}{}, 946 }, 947 { // decode a number which is too large to fit in a float64 948 input: "[1e900]", 949 value: []interface{}{}, 950 }, 951 { // many nested arrays openings 952 input: "[[[[[[", 953 value: []interface{}{}, 954 }, 955 { // decode a map with value type mismatch and missing closing character 956 input: "{\"\":0", 957 value: map[string]string{}, 958 }, 959 { // decode a struct with value type mismatch and missing closing character 960 input: "{\"E\":\"\"", 961 value: struct{ E uint8 }{}, 962 }, 963 { // decode a map with value type mismatch 964 input: "{\"\":0}", 965 value: map[string]string{}, 966 }, 967 { // decode number with exponent into integer field 968 input: "{\"e\":0e0}", 969 value: struct{ E uint8 }{}, 970 }, 971 { // decode invalid integer representation into integer field 972 input: "{\"e\":00}", 973 value: struct{ E uint8 }{}, 974 }, 975 { // decode unterminated array into byte slice 976 input: "{\"F\":[", 977 value: struct{ F []byte }{}, 978 }, 979 { // attempt to decode string into in 980 input: "{\"S\":\"\"}", 981 value: struct { 982 S int `json:",string"` 983 }{}, 984 }, 985 { // decode object with null key into map 986 input: "{null:0}", 987 value: map[string]interface{}{}, 988 }, 989 { // decode unquoted integer into struct field with string tag 990 input: "{\"S\":0}", 991 value: struct { 992 S int `json:",string"` 993 }{}, 994 }, 995 { // invalid base64 content when decoding string into byte slice 996 input: "{\"F\":\"0\"}", 997 value: struct{ F []byte }{}, 998 }, 999 { // decode an object with a "null" string as key 1000 input: "{\"null\":null}", 1001 value: struct { 1002 S int `json:",string"` 1003 }{}, 1004 }, 1005 { // decode an invalid floating point number representation into an integer field with string tag 1006 input: "{\"s\":8e800}", 1007 value: struct { 1008 S int `json:",string"` 1009 }{}, 1010 }, 1011 { // decode a string with leading zeroes into an integer field with string tag 1012 input: "{\"S\":\"00\"}", 1013 value: struct { 1014 S int `json:",string"` 1015 }{}, 1016 }, 1017 { // decode a string with invalid leading sign and zeroes into an integer field with string tag 1018 input: "{\"S\":\"+00\"}", 1019 value: struct { 1020 S int `json:",string"` 1021 }{}, 1022 }, 1023 { // decode a string with valid leading sign and zeroes into an integer field with string tag 1024 input: "{\"S\":\"-00\"}", 1025 value: struct { 1026 S int `json:",string"` 1027 }{}, 1028 }, 1029 { // decode non-ascii string into integer field with string tag 1030 input: "{\"ſ\":\"\xbf\"}", 1031 value: struct { 1032 S int `json:",string"` 1033 }{}, 1034 }, 1035 { // decode a valid floating point number representation into an integer field with string tag 1036 input: "{\"S\":0.0}", 1037 value: struct { 1038 S int `json:",string"` 1039 }{}, 1040 }, 1041 { // decode string with invalid leading sign to integer field with string tag 1042 input: "{\"S\":\"+0\"}", 1043 value: struct { 1044 S int `json:",string"` 1045 }{}, 1046 }, 1047 { // decode string with valid leading sign to integer field with string tag 1048 input: "{\"S\":\"-0\"}", 1049 value: struct { 1050 S int `json:",string"` 1051 }{}, 1052 }, 1053 { // decode string with object representation to integer field with string tag 1054 input: "{\"s\":{}}", 1055 value: struct { 1056 S int `json:",string"` 1057 }{}, 1058 }, 1059 { // decoding integer with leading zeroes 1060 input: "{\"o\":00}", 1061 value: struct{ O **int }{}, 1062 }, 1063 { // codeding string with invalid float representation into integer field with string tag 1064 input: "{\"s\":\"0.\"}", 1065 value: struct { 1066 S int `json:",string"` 1067 }{}, 1068 }, 1069 { // malformed negative integer in object value 1070 input: "{\"N\":-00}", 1071 value: struct{ N *int }{}, 1072 }, 1073 { // integer overflow 1074 input: "{\"a\":9223372036854775808}", 1075 value: struct { 1076 A int `json:",omitempty"` 1077 }{}, 1078 }, 1079 { // decode string with number followed by random byte into integer field with string tag 1080 input: "{\"s\":\"0]\"}", 1081 value: struct { 1082 S int `json:",string"` 1083 }{}, 1084 }, 1085 { // decode object into integer field 1086 input: "{\"n\":{}}", 1087 value: struct{ N *int }{}, 1088 }, 1089 { // decode negative integer into unsigned type 1090 input: "{\"E\":-0}", 1091 value: struct{ E uint8 }{}, 1092 }, 1093 { // decode string with number followed by random byte into integer field with string tag 1094 input: "{\"s\":\"03�\"}", 1095 value: struct { 1096 S int `json:",string"` 1097 }{}, 1098 }, 1099 { // decode string with leading zeroes into integer field with string tag 1100 input: "{\"s\":\"03\"}", 1101 value: struct { 1102 S int `json:",string"` 1103 }{S: 3}, 1104 }, 1105 { // decode string containing what looks like an object into integer field with string tag 1106 input: "{\"S\":\"{}\"}", 1107 value: struct { 1108 S int `json:",string"` 1109 }{}, 1110 }, 1111 { // decode an empty string followed by the same field with a null value into a byte slice 1112 input: "{\"F\":\"\",\"F\":null}", 1113 value: struct{ F []byte }{}, 1114 }, 1115 { // decode string containing a float into an integer field with string tag 1116 input: "{\"S\":\"0e0\"}", 1117 value: struct { 1118 S int `json:",string"` 1119 }{}, 1120 }, 1121 { // decode string with negative sign into a an integer field with string tag 1122 input: "{\"s\":\"-\"}", 1123 value: struct { 1124 S int `json:",string"` 1125 }{}, 1126 }, 1127 { // decode string with positive sign into a an integer field with string tag 1128 input: "{\"s\":\"+\"}", 1129 value: struct { 1130 S int `json:",string"` 1131 }{}, 1132 }, 1133 { // decode an integer into a json unmarshaler 1134 input: "{\"q\":0}", 1135 value: struct { 1136 Q testMarshaller 1137 }{}, 1138 }, 1139 // This test fails because it appears that the encoding/json package 1140 // will decode "q" before "s", so it returns an error about "q" being of 1141 // the wrong type while this package will prase object keys in the order 1142 // that they appear in the JSON input, so it detects the error from "s" 1143 // first. 1144 // 1145 //{ 1146 // input: "{\"s\":0,\"q\":0}", 1147 // value: struct { 1148 // Q testMarshaller 1149 // S int `json:",string"` 1150 // }{}, 1151 //}, 1152 } 1153 1154 for _, test := range tests { 1155 t.Run("", func(t *testing.T) { 1156 var ptr1 interface{} 1157 var ptr2 interface{} 1158 1159 if test.value != nil { 1160 ptr1 = reflect.New(reflect.TypeOf(test.value)).Interface() 1161 ptr2 = reflect.New(reflect.TypeOf(test.value)).Interface() 1162 } 1163 1164 err1 := json.Unmarshal([]byte(test.input), ptr1) 1165 err2 := Unmarshal([]byte(test.input), ptr2) 1166 1167 if reflect.TypeOf(err1) != reflect.TypeOf(err2) { 1168 t.Error("errors mismatch") 1169 t.Logf("expected: %T: %v", err1, err1) 1170 t.Logf("found: %T: %v", err2, err2) 1171 } else if err1 == nil && test.value != nil { 1172 if value := reflect.ValueOf(ptr2).Elem().Interface(); !reflect.DeepEqual(test.value, value) { 1173 t.Error("values mismatch") 1174 t.Logf("expected: %#v", test.value) 1175 t.Logf("found: %#v", value) 1176 } 1177 } 1178 }) 1179 } 1180 } 1181 1182 func BenchmarkEasyjsonUnmarshalSmallStruct(b *testing.B) { 1183 type Hashtag struct { 1184 Indices []int `json:"indices"` 1185 Text string `json:"text"` 1186 } 1187 1188 //easyjson:json 1189 type Entities struct { 1190 Hashtags []Hashtag `json:"hashtags"` 1191 Urls []*string `json:"urls"` 1192 UserMentions []*string `json:"user_mentions"` 1193 } 1194 1195 var json = []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`) 1196 1197 for i := 0; i < b.N; i++ { 1198 var value Entities 1199 if err := Unmarshal(json, &value); err != nil { 1200 b.Fatal(err) 1201 } 1202 } 1203 } 1204 1205 type testMarshaller struct { 1206 v string 1207 } 1208 1209 func (m *testMarshaller) MarshalJSON() ([]byte, error) { 1210 return Marshal(m.v) 1211 } 1212 1213 func (m *testMarshaller) UnmarshalJSON(data []byte) error { 1214 return Unmarshal(data, &m.v) 1215 } 1216 1217 func TestGithubIssue11(t *testing.T) { 1218 // https://github.com/segmentio/encoding/issues/11 1219 v := struct{ F float64 }{ 1220 F: math.NaN(), 1221 } 1222 1223 _, err := Marshal(v) 1224 if err == nil { 1225 t.Error("no error returned when marshalling NaN value") 1226 } else if s := err.Error(); !strings.Contains(s, "NaN") { 1227 t.Error("error returned when marshalling NaN value does not mention 'NaN':", s) 1228 } else { 1229 t.Log(s) 1230 } 1231 } 1232 1233 type Issue13 struct { 1234 Stringer fmt.Stringer 1235 Field int `json:"MyInt"` 1236 } 1237 1238 type S string 1239 1240 func (s S) String() string { return string(s) } 1241 1242 func TestGithubIssue13(t *testing.T) { 1243 // https://github.com/segmentio/encoding/issues/13 1244 v := Issue13{} 1245 1246 b, err := Marshal(v) 1247 if err != nil { 1248 t.Error("unexpected errror:", err) 1249 } else { 1250 t.Log(string(b)) 1251 } 1252 1253 v = Issue13{Stringer: S("")} 1254 if err := Unmarshal([]byte(`{"Stringer":null}`), &v); err != nil { 1255 t.Error("unexpected error:", err) 1256 } 1257 if v.Stringer != nil { 1258 t.Error("Stringer field was not overwritten") 1259 } 1260 1261 v = Issue13{} 1262 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1263 t.Error("expected error but decoding string value into nil fmt.Stringer but got <nil>") 1264 } 1265 1266 v = Issue13{Stringer: S("")} 1267 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1268 t.Error("expected error but decoding string value into non-pointer fmt.Stringer but got <nil>") 1269 } 1270 1271 s := S("") 1272 v = Issue13{Stringer: &s} 1273 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err != nil { 1274 t.Error("unexpected error decoding string value into pointer fmt.Stringer:", err) 1275 } 1276 } 1277 1278 func TestGithubIssue15(t *testing.T) { 1279 // https://github.com/segmentio/encoding/issues/15 1280 tests := []struct { 1281 m interface{} 1282 s string 1283 }{ 1284 { 1285 m: map[uint]bool{1: true, 123: true, 333: true, 42: true}, 1286 s: `{"1":true,"123":true,"333":true,"42":true}`, 1287 }, 1288 { 1289 m: map[int]bool{-1: true, -123: true, 333: true, 42: true}, 1290 s: `{"-1":true,"-123":true,"333":true,"42":true}`, 1291 }, 1292 } 1293 1294 for _, test := range tests { 1295 b, _ := Marshal(test.m) 1296 1297 if string(b) != test.s { 1298 t.Error("map with integer keys must be ordered by their string representation, got", string(b)) 1299 } 1300 1301 } 1302 } 1303 1304 type sliceA []byte 1305 1306 func (sliceA) MarshalJSON() ([]byte, error) { 1307 return []byte(`"A"`), nil 1308 } 1309 1310 type sliceB []byte 1311 1312 func (sliceB) MarshalText() ([]byte, error) { 1313 return []byte("B"), nil 1314 } 1315 1316 type mapA map[string]string 1317 1318 func (mapA) MarshalJSON() ([]byte, error) { 1319 return []byte(`"A"`), nil 1320 } 1321 1322 type mapB map[string]string 1323 1324 func (mapB) MarshalText() ([]byte, error) { 1325 return []byte("B"), nil 1326 } 1327 1328 type intPtrA int 1329 1330 func (*intPtrA) MarshalJSON() ([]byte, error) { 1331 return []byte(`"A"`), nil 1332 } 1333 1334 type intPtrB int 1335 1336 func (*intPtrB) MarshalText() ([]byte, error) { 1337 return []byte("B"), nil 1338 } 1339 1340 type structA struct{ I intPtrA } 1341 type structB struct{ I intPtrB } 1342 type structC struct{ M Marshaler } 1343 type structD struct{ M encoding.TextMarshaler } 1344 1345 func TestGithubIssue16(t *testing.T) { 1346 // https://github.com/segmentio/encoding/issues/16 1347 tests := []struct { 1348 value interface{} 1349 output string 1350 }{ 1351 {value: sliceA(nil), output: `"A"`}, 1352 {value: sliceB(nil), output: `"B"`}, 1353 {value: mapA(nil), output: `"A"`}, 1354 {value: mapB(nil), output: `"B"`}, 1355 {value: intPtrA(1), output: `1`}, 1356 {value: intPtrB(2), output: `2`}, 1357 {value: new(intPtrA), output: `"A"`}, 1358 {value: new(intPtrB), output: `"B"`}, 1359 {value: (*intPtrA)(nil), output: `null`}, 1360 {value: (*intPtrB)(nil), output: `null`}, 1361 {value: structA{I: 1}, output: `{"I":1}`}, 1362 {value: structB{I: 2}, output: `{"I":2}`}, 1363 {value: structC{}, output: `{"M":null}`}, 1364 {value: structD{}, output: `{"M":null}`}, 1365 {value: &structA{I: 1}, output: `{"I":"A"}`}, 1366 {value: &structB{I: 2}, output: `{"I":"B"}`}, 1367 {value: &structC{}, output: `{"M":null}`}, 1368 {value: &structD{}, output: `{"M":null}`}, 1369 } 1370 1371 for _, test := range tests { 1372 t.Run(fmt.Sprintf("%T", test.value), func(t *testing.T) { 1373 if b, _ := Marshal(test.value); string(b) != test.output { 1374 t.Errorf(`%s != %s`, string(b), test.output) 1375 } 1376 }) 1377 } 1378 } 1379 1380 func TestDecoderInputOffset(t *testing.T) { 1381 checkOffset := func(o, expected int64) { 1382 if o != expected { 1383 t.Error("unexpected input offset", o, expected) 1384 } 1385 } 1386 1387 b := []byte(`{"userId": "blah"}{"userId": "blah"} 1388 {"userId": "blah"}{"num": 0}`) 1389 d := NewDecoder(bytes.NewReader(b)) 1390 1391 var expected int64 1392 checkOffset(d.InputOffset(), expected) 1393 1394 var a struct { 1395 UserId string `json:"userId"` 1396 } 1397 1398 if err := d.Decode(&a); err != nil { 1399 t.Error("unexpected decode error", err) 1400 } 1401 expected = int64(18) 1402 checkOffset(d.InputOffset(), expected) 1403 1404 if err := d.Decode(&a); err != nil { 1405 t.Error("unexpected decode error", err) 1406 } 1407 expected = int64(38) 1408 checkOffset(d.InputOffset(), expected) 1409 1410 if err := d.Decode(&a); err != nil { 1411 t.Error("unexpected decode error", err) 1412 } 1413 expected = int64(56) 1414 checkOffset(d.InputOffset(), expected) 1415 1416 var z struct { 1417 Num int64 `json:"num"` 1418 } 1419 if err := d.Decode(&z); err != nil { 1420 t.Error("unexpected decode error", err) 1421 } 1422 expected = int64(66) 1423 checkOffset(d.InputOffset(), expected) 1424 } 1425 1426 func TestGithubIssue18(t *testing.T) { 1427 // https://github.com/segmentio/encoding/issues/18 1428 b := []byte(`{ 1429 "userId": "blah", 1430 }`) 1431 1432 d := NewDecoder(bytes.NewReader(b)) 1433 1434 var a struct { 1435 UserId string `json:"userId"` 1436 } 1437 switch err := d.Decode(&a).(type) { 1438 case *SyntaxError: 1439 default: 1440 t.Error("expected syntax error but found:", err) 1441 } 1442 1443 for i := 1; i <= 18; i++ { // up to the invalid ',' character 1444 d := NewDecoder(bytes.NewReader(b[:i])) // cut somewhere in the middle 1445 switch err := d.Decode(&a); err { 1446 case io.ErrUnexpectedEOF: 1447 default: 1448 t.Error("expected 'unexpected EOF' error but found:", err) 1449 } 1450 } 1451 } 1452 1453 func TestGithubIssue23(t *testing.T) { 1454 t.Run("marshal-1", func(t *testing.T) { 1455 type d struct{ S map[string]string } 1456 1457 b, _ := Marshal(map[string]d{"1": {S: map[string]string{"2": "3"}}}) 1458 if string(b) != `{"1":{"S":{"2":"3"}}}` { 1459 t.Error(string(b)) 1460 } 1461 }) 1462 1463 t.Run("marshal-2", func(t *testing.T) { 1464 type testInner struct { 1465 InnerMap map[string]string `json:"inner_map"` 1466 } 1467 1468 type testOuter struct { 1469 OuterMap map[string]testInner `json:"outer_map"` 1470 } 1471 1472 b, _ := Marshal(testOuter{ 1473 OuterMap: map[string]testInner{ 1474 "outer": { 1475 InnerMap: map[string]string{"inner": "value"}, 1476 }, 1477 }, 1478 }) 1479 1480 if string(b) != `{"outer_map":{"outer":{"inner_map":{"inner":"value"}}}}` { 1481 t.Error(string(b)) 1482 } 1483 }) 1484 1485 t.Run("marshal-3", func(t *testing.T) { 1486 type A struct{ A map[string]string } 1487 type B struct{ B map[string]A } 1488 type C struct{ C map[string]B } 1489 1490 b, _ := Marshal(C{ 1491 C: map[string]B{ 1492 "1": B{ 1493 B: map[string]A{ 1494 "2": A{ 1495 A: map[string]string{"3": "!"}, 1496 }, 1497 }, 1498 }, 1499 }, 1500 }) 1501 1502 if string(b) != `{"C":{"1":{"B":{"2":{"A":{"3":"!"}}}}}}` { 1503 t.Error(string(b)) 1504 } 1505 }) 1506 1507 t.Run("unmarshal-1", func(t *testing.T) { 1508 var d struct{ S map[string]string } 1509 1510 if err := Unmarshal([]byte(`{"1":{"S":{"2":"3"}}}`), &d); err != nil { 1511 t.Error(err) 1512 } 1513 }) 1514 } 1515 1516 func TestGithubIssue26(t *testing.T) { 1517 type interfaceType interface{} 1518 1519 var value interfaceType 1520 var data = []byte(`{}`) 1521 1522 if err := Unmarshal(data, &value); err != nil { 1523 t.Error(err) 1524 } 1525 } 1526 1527 func TestGithubIssue28(t *testing.T) { 1528 type A struct { 1529 Err error `json:"err"` 1530 } 1531 1532 if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil { 1533 t.Error(err) 1534 } else if string(b) != `{"err":{}}` { 1535 t.Error(string(b)) 1536 } 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 }