1// Copyright 2011 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package json 6 7import ( 8 "bytes" 9 "encoding" 10 "fmt" 11 "log" 12 "math" 13 "reflect" 14 "regexp" 15 "runtime/debug" 16 "strconv" 17 "testing" 18) 19 20type Optionals struct { 21 Sr string `json:"sr"` 22 So string `json:"so,omitempty"` 23 Sw string `json:"-"` 24 25 Ir int `json:"omitempty"` // actually named omitempty, not an option 26 Io int `json:"io,omitempty"` 27 28 Slr []string `json:"slr,random"` 29 Slo []string `json:"slo,omitempty"` 30 31 Mr map[string]any `json:"mr"` 32 Mo map[string]any `json:",omitempty"` 33 34 Fr float64 `json:"fr"` 35 Fo float64 `json:"fo,omitempty"` 36 37 Br bool `json:"br"` 38 Bo bool `json:"bo,omitempty"` 39 40 Ur uint `json:"ur"` 41 Uo uint `json:"uo,omitempty"` 42 43 Str struct{} `json:"str"` 44 Sto struct{} `json:"sto,omitempty"` 45} 46 47func TestOmitEmpty(t *testing.T) { 48 var want = `{ 49 "sr": "", 50 "omitempty": 0, 51 "slr": null, 52 "mr": {}, 53 "fr": 0, 54 "br": false, 55 "ur": 0, 56 "str": {}, 57 "sto": {} 58}` 59 var o Optionals 60 o.Sw = "something" 61 o.Mr = map[string]any{} 62 o.Mo = map[string]any{} 63 64 got, err := MarshalIndent(&o, "", " ") 65 if err != nil { 66 t.Fatalf("MarshalIndent error: %v", err) 67 } 68 if got := string(got); got != want { 69 t.Errorf("MarshalIndent:\n\tgot: %s\n\twant: %s\n", indentNewlines(got), indentNewlines(want)) 70 } 71} 72 73type StringTag struct { 74 BoolStr bool `json:",string"` 75 IntStr int64 `json:",string"` 76 UintptrStr uintptr `json:",string"` 77 StrStr string `json:",string"` 78 NumberStr Number `json:",string"` 79} 80 81func TestRoundtripStringTag(t *testing.T) { 82 tests := []struct { 83 CaseName 84 in StringTag 85 want string // empty to just test that we roundtrip 86 }{{ 87 CaseName: Name("AllTypes"), 88 in: StringTag{ 89 BoolStr: true, 90 IntStr: 42, 91 UintptrStr: 44, 92 StrStr: "xzbit", 93 NumberStr: "46", 94 }, 95 want: `{ 96 "BoolStr": "true", 97 "IntStr": "42", 98 "UintptrStr": "44", 99 "StrStr": "\"xzbit\"", 100 "NumberStr": "46" 101}`, 102 }, { 103 // See golang.org/issues/38173. 104 CaseName: Name("StringDoubleEscapes"), 105 in: StringTag{ 106 StrStr: "\b\f\n\r\t\"\\", 107 NumberStr: "0", // just to satisfy the roundtrip 108 }, 109 want: `{ 110 "BoolStr": "false", 111 "IntStr": "0", 112 "UintptrStr": "0", 113 "StrStr": "\"\\b\\f\\n\\r\\t\\\"\\\\\"", 114 "NumberStr": "0" 115}`, 116 }} 117 for _, tt := range tests { 118 t.Run(tt.Name, func(t *testing.T) { 119 got, err := MarshalIndent(&tt.in, "", "\t") 120 if err != nil { 121 t.Fatalf("%s: MarshalIndent error: %v", tt.Where, err) 122 } 123 if got := string(got); got != tt.want { 124 t.Fatalf("%s: MarshalIndent:\n\tgot: %s\n\twant: %s", tt.Where, stripWhitespace(got), stripWhitespace(tt.want)) 125 } 126 127 // Verify that it round-trips. 128 var s2 StringTag 129 if err := Unmarshal(got, &s2); err != nil { 130 t.Fatalf("%s: Decode error: %v", tt.Where, err) 131 } 132 if !reflect.DeepEqual(s2, tt.in) { 133 t.Fatalf("%s: Decode:\n\tinput: %s\n\tgot: %#v\n\twant: %#v", tt.Where, indentNewlines(string(got)), s2, tt.in) 134 } 135 }) 136 } 137} 138 139// byte slices are special even if they're renamed types. 140type renamedByte byte 141type renamedByteSlice []byte 142type renamedRenamedByteSlice []renamedByte 143 144func TestEncodeRenamedByteSlice(t *testing.T) { 145 s := renamedByteSlice("abc") 146 got, err := Marshal(s) 147 if err != nil { 148 t.Fatalf("Marshal error: %v", err) 149 } 150 want := `"YWJj"` 151 if string(got) != want { 152 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 153 } 154 r := renamedRenamedByteSlice("abc") 155 got, err = Marshal(r) 156 if err != nil { 157 t.Fatalf("Marshal error: %v", err) 158 } 159 if string(got) != want { 160 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 161 } 162} 163 164type SamePointerNoCycle struct { 165 Ptr1, Ptr2 *SamePointerNoCycle 166} 167 168var samePointerNoCycle = &SamePointerNoCycle{} 169 170type PointerCycle struct { 171 Ptr *PointerCycle 172} 173 174var pointerCycle = &PointerCycle{} 175 176type PointerCycleIndirect struct { 177 Ptrs []any 178} 179 180type RecursiveSlice []RecursiveSlice 181 182var ( 183 pointerCycleIndirect = &PointerCycleIndirect{} 184 mapCycle = make(map[string]any) 185 sliceCycle = []any{nil} 186 sliceNoCycle = []any{nil, nil} 187 recursiveSliceCycle = []RecursiveSlice{nil} 188) 189 190func init() { 191 ptr := &SamePointerNoCycle{} 192 samePointerNoCycle.Ptr1 = ptr 193 samePointerNoCycle.Ptr2 = ptr 194 195 pointerCycle.Ptr = pointerCycle 196 pointerCycleIndirect.Ptrs = []any{pointerCycleIndirect} 197 198 mapCycle["x"] = mapCycle 199 sliceCycle[0] = sliceCycle 200 sliceNoCycle[1] = sliceNoCycle[:1] 201 for i := startDetectingCyclesAfter; i > 0; i-- { 202 sliceNoCycle = []any{sliceNoCycle} 203 } 204 recursiveSliceCycle[0] = recursiveSliceCycle 205} 206 207func TestSamePointerNoCycle(t *testing.T) { 208 if _, err := Marshal(samePointerNoCycle); err != nil { 209 t.Fatalf("Marshal error: %v", err) 210 } 211} 212 213func TestSliceNoCycle(t *testing.T) { 214 if _, err := Marshal(sliceNoCycle); err != nil { 215 t.Fatalf("Marshal error: %v", err) 216 } 217} 218 219func TestUnsupportedValues(t *testing.T) { 220 tests := []struct { 221 CaseName 222 in any 223 }{ 224 {Name(""), math.NaN()}, 225 {Name(""), math.Inf(-1)}, 226 {Name(""), math.Inf(1)}, 227 {Name(""), pointerCycle}, 228 {Name(""), pointerCycleIndirect}, 229 {Name(""), mapCycle}, 230 {Name(""), sliceCycle}, 231 {Name(""), recursiveSliceCycle}, 232 } 233 for _, tt := range tests { 234 t.Run(tt.Name, func(t *testing.T) { 235 if _, err := Marshal(tt.in); err != nil { 236 if _, ok := err.(*UnsupportedValueError); !ok { 237 t.Errorf("%s: Marshal error:\n\tgot: %T\n\twant: %T", tt.Where, err, new(UnsupportedValueError)) 238 } 239 } else { 240 t.Errorf("%s: Marshal error: got nil, want non-nil", tt.Where) 241 } 242 }) 243 } 244} 245 246// Issue 43207 247func TestMarshalTextFloatMap(t *testing.T) { 248 m := map[textfloat]string{ 249 textfloat(math.NaN()): "1", 250 textfloat(math.NaN()): "1", 251 } 252 got, err := Marshal(m) 253 if err != nil { 254 t.Errorf("Marshal error: %v", err) 255 } 256 want := `{"TF:NaN":"1","TF:NaN":"1"}` 257 if string(got) != want { 258 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 259 } 260} 261 262// Ref has Marshaler and Unmarshaler methods with pointer receiver. 263type Ref int 264 265func (*Ref) MarshalJSON() ([]byte, error) { 266 return []byte(`"ref"`), nil 267} 268 269func (r *Ref) UnmarshalJSON([]byte) error { 270 *r = 12 271 return nil 272} 273 274// Val has Marshaler methods with value receiver. 275type Val int 276 277func (Val) MarshalJSON() ([]byte, error) { 278 return []byte(`"val"`), nil 279} 280 281// RefText has Marshaler and Unmarshaler methods with pointer receiver. 282type RefText int 283 284func (*RefText) MarshalText() ([]byte, error) { 285 return []byte(`"ref"`), nil 286} 287 288func (r *RefText) UnmarshalText([]byte) error { 289 *r = 13 290 return nil 291} 292 293// ValText has Marshaler methods with value receiver. 294type ValText int 295 296func (ValText) MarshalText() ([]byte, error) { 297 return []byte(`"val"`), nil 298} 299 300func TestRefValMarshal(t *testing.T) { 301 var s = struct { 302 R0 Ref 303 R1 *Ref 304 R2 RefText 305 R3 *RefText 306 V0 Val 307 V1 *Val 308 V2 ValText 309 V3 *ValText 310 }{ 311 R0: 12, 312 R1: new(Ref), 313 R2: 14, 314 R3: new(RefText), 315 V0: 13, 316 V1: new(Val), 317 V2: 15, 318 V3: new(ValText), 319 } 320 const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}` 321 b, err := Marshal(&s) 322 if err != nil { 323 t.Fatalf("Marshal error: %v", err) 324 } 325 if got := string(b); got != want { 326 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 327 } 328} 329 330// C implements Marshaler and returns unescaped JSON. 331type C int 332 333func (C) MarshalJSON() ([]byte, error) { 334 return []byte(`"<&>"`), nil 335} 336 337// CText implements Marshaler and returns unescaped text. 338type CText int 339 340func (CText) MarshalText() ([]byte, error) { 341 return []byte(`"<&>"`), nil 342} 343 344func TestMarshalerEscaping(t *testing.T) { 345 var c C 346 want := `"\u003c\u0026\u003e"` 347 b, err := Marshal(c) 348 if err != nil { 349 t.Fatalf("Marshal error: %v", err) 350 } 351 if got := string(b); got != want { 352 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 353 } 354 355 var ct CText 356 want = `"\"\u003c\u0026\u003e\""` 357 b, err = Marshal(ct) 358 if err != nil { 359 t.Fatalf("Marshal error: %v", err) 360 } 361 if got := string(b); got != want { 362 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 363 } 364} 365 366func TestAnonymousFields(t *testing.T) { 367 tests := []struct { 368 CaseName 369 makeInput func() any // Function to create input value 370 want string // Expected JSON output 371 }{{ 372 // Both S1 and S2 have a field named X. From the perspective of S, 373 // it is ambiguous which one X refers to. 374 // This should not serialize either field. 375 CaseName: Name("AmbiguousField"), 376 makeInput: func() any { 377 type ( 378 S1 struct{ x, X int } 379 S2 struct{ x, X int } 380 S struct { 381 S1 382 S2 383 } 384 ) 385 return S{S1{1, 2}, S2{3, 4}} 386 }, 387 want: `{}`, 388 }, { 389 CaseName: Name("DominantField"), 390 // Both S1 and S2 have a field named X, but since S has an X field as 391 // well, it takes precedence over S1.X and S2.X. 392 makeInput: func() any { 393 type ( 394 S1 struct{ x, X int } 395 S2 struct{ x, X int } 396 S struct { 397 S1 398 S2 399 x, X int 400 } 401 ) 402 return S{S1{1, 2}, S2{3, 4}, 5, 6} 403 }, 404 want: `{"X":6}`, 405 }, { 406 // Unexported embedded field of non-struct type should not be serialized. 407 CaseName: Name("UnexportedEmbeddedInt"), 408 makeInput: func() any { 409 type ( 410 myInt int 411 S struct{ myInt } 412 ) 413 return S{5} 414 }, 415 want: `{}`, 416 }, { 417 // Exported embedded field of non-struct type should be serialized. 418 CaseName: Name("ExportedEmbeddedInt"), 419 makeInput: func() any { 420 type ( 421 MyInt int 422 S struct{ MyInt } 423 ) 424 return S{5} 425 }, 426 want: `{"MyInt":5}`, 427 }, { 428 // Unexported embedded field of pointer to non-struct type 429 // should not be serialized. 430 CaseName: Name("UnexportedEmbeddedIntPointer"), 431 makeInput: func() any { 432 type ( 433 myInt int 434 S struct{ *myInt } 435 ) 436 s := S{new(myInt)} 437 *s.myInt = 5 438 return s 439 }, 440 want: `{}`, 441 }, { 442 // Exported embedded field of pointer to non-struct type 443 // should be serialized. 444 CaseName: Name("ExportedEmbeddedIntPointer"), 445 makeInput: func() any { 446 type ( 447 MyInt int 448 S struct{ *MyInt } 449 ) 450 s := S{new(MyInt)} 451 *s.MyInt = 5 452 return s 453 }, 454 want: `{"MyInt":5}`, 455 }, { 456 // Exported fields of embedded structs should have their 457 // exported fields be serialized regardless of whether the struct types 458 // themselves are exported. 459 CaseName: Name("EmbeddedStruct"), 460 makeInput: func() any { 461 type ( 462 s1 struct{ x, X int } 463 S2 struct{ y, Y int } 464 S struct { 465 s1 466 S2 467 } 468 ) 469 return S{s1{1, 2}, S2{3, 4}} 470 }, 471 want: `{"X":2,"Y":4}`, 472 }, { 473 // Exported fields of pointers to embedded structs should have their 474 // exported fields be serialized regardless of whether the struct types 475 // themselves are exported. 476 CaseName: Name("EmbeddedStructPointer"), 477 makeInput: func() any { 478 type ( 479 s1 struct{ x, X int } 480 S2 struct{ y, Y int } 481 S struct { 482 *s1 483 *S2 484 } 485 ) 486 return S{&s1{1, 2}, &S2{3, 4}} 487 }, 488 want: `{"X":2,"Y":4}`, 489 }, { 490 // Exported fields on embedded unexported structs at multiple levels 491 // of nesting should still be serialized. 492 CaseName: Name("NestedStructAndInts"), 493 makeInput: func() any { 494 type ( 495 MyInt1 int 496 MyInt2 int 497 myInt int 498 s2 struct { 499 MyInt2 500 myInt 501 } 502 s1 struct { 503 MyInt1 504 myInt 505 s2 506 } 507 S struct { 508 s1 509 myInt 510 } 511 ) 512 return S{s1{1, 2, s2{3, 4}}, 6} 513 }, 514 want: `{"MyInt1":1,"MyInt2":3}`, 515 }, { 516 // If an anonymous struct pointer field is nil, we should ignore 517 // the embedded fields behind it. Not properly doing so may 518 // result in the wrong output or reflect panics. 519 CaseName: Name("EmbeddedFieldBehindNilPointer"), 520 makeInput: func() any { 521 type ( 522 S2 struct{ Field string } 523 S struct{ *S2 } 524 ) 525 return S{} 526 }, 527 want: `{}`, 528 }} 529 530 for _, tt := range tests { 531 t.Run(tt.Name, func(t *testing.T) { 532 b, err := Marshal(tt.makeInput()) 533 if err != nil { 534 t.Fatalf("%s: Marshal error: %v", tt.Where, err) 535 } 536 if string(b) != tt.want { 537 t.Fatalf("%s: Marshal:\n\tgot: %s\n\twant: %s", tt.Where, b, tt.want) 538 } 539 }) 540 } 541} 542 543type BugA struct { 544 S string 545} 546 547type BugB struct { 548 BugA 549 S string 550} 551 552type BugC struct { 553 S string 554} 555 556// Legal Go: We never use the repeated embedded field (S). 557type BugX struct { 558 A int 559 BugA 560 BugB 561} 562 563// golang.org/issue/16042. 564// Even if a nil interface value is passed in, as long as 565// it implements Marshaler, it should be marshaled. 566type nilJSONMarshaler string 567 568func (nm *nilJSONMarshaler) MarshalJSON() ([]byte, error) { 569 if nm == nil { 570 return Marshal("0zenil0") 571 } 572 return Marshal("zenil:" + string(*nm)) 573} 574 575// golang.org/issue/34235. 576// Even if a nil interface value is passed in, as long as 577// it implements encoding.TextMarshaler, it should be marshaled. 578type nilTextMarshaler string 579 580func (nm *nilTextMarshaler) MarshalText() ([]byte, error) { 581 if nm == nil { 582 return []byte("0zenil0"), nil 583 } 584 return []byte("zenil:" + string(*nm)), nil 585} 586 587// See golang.org/issue/16042 and golang.org/issue/34235. 588func TestNilMarshal(t *testing.T) { 589 tests := []struct { 590 CaseName 591 in any 592 want string 593 }{ 594 {Name(""), nil, `null`}, 595 {Name(""), new(float64), `0`}, 596 {Name(""), []any(nil), `null`}, 597 {Name(""), []string(nil), `null`}, 598 {Name(""), map[string]string(nil), `null`}, 599 {Name(""), []byte(nil), `null`}, 600 {Name(""), struct{ M string }{"gopher"}, `{"M":"gopher"}`}, 601 {Name(""), struct{ M Marshaler }{}, `{"M":null}`}, 602 {Name(""), struct{ M Marshaler }{(*nilJSONMarshaler)(nil)}, `{"M":"0zenil0"}`}, 603 {Name(""), struct{ M any }{(*nilJSONMarshaler)(nil)}, `{"M":null}`}, 604 {Name(""), struct{ M encoding.TextMarshaler }{}, `{"M":null}`}, 605 {Name(""), struct{ M encoding.TextMarshaler }{(*nilTextMarshaler)(nil)}, `{"M":"0zenil0"}`}, 606 {Name(""), struct{ M any }{(*nilTextMarshaler)(nil)}, `{"M":null}`}, 607 } 608 for _, tt := range tests { 609 t.Run(tt.Name, func(t *testing.T) { 610 switch got, err := Marshal(tt.in); { 611 case err != nil: 612 t.Fatalf("%s: Marshal error: %v", tt.Where, err) 613 case string(got) != tt.want: 614 t.Fatalf("%s: Marshal:\n\tgot: %s\n\twant: %s", tt.Where, got, tt.want) 615 } 616 }) 617 } 618} 619 620// Issue 5245. 621func TestEmbeddedBug(t *testing.T) { 622 v := BugB{ 623 BugA{"A"}, 624 "B", 625 } 626 b, err := Marshal(v) 627 if err != nil { 628 t.Fatal("Marshal error:", err) 629 } 630 want := `{"S":"B"}` 631 got := string(b) 632 if got != want { 633 t.Fatalf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 634 } 635 // Now check that the duplicate field, S, does not appear. 636 x := BugX{ 637 A: 23, 638 } 639 b, err = Marshal(x) 640 if err != nil { 641 t.Fatal("Marshal error:", err) 642 } 643 want = `{"A":23}` 644 got = string(b) 645 if got != want { 646 t.Fatalf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 647 } 648} 649 650type BugD struct { // Same as BugA after tagging. 651 XXX string `json:"S"` 652} 653 654// BugD's tagged S field should dominate BugA's. 655type BugY struct { 656 BugA 657 BugD 658} 659 660// Test that a field with a tag dominates untagged fields. 661func TestTaggedFieldDominates(t *testing.T) { 662 v := BugY{ 663 BugA{"BugA"}, 664 BugD{"BugD"}, 665 } 666 b, err := Marshal(v) 667 if err != nil { 668 t.Fatal("Marshal error:", err) 669 } 670 want := `{"S":"BugD"}` 671 got := string(b) 672 if got != want { 673 t.Fatalf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 674 } 675} 676 677// There are no tags here, so S should not appear. 678type BugZ struct { 679 BugA 680 BugC 681 BugY // Contains a tagged S field through BugD; should not dominate. 682} 683 684func TestDuplicatedFieldDisappears(t *testing.T) { 685 v := BugZ{ 686 BugA{"BugA"}, 687 BugC{"BugC"}, 688 BugY{ 689 BugA{"nested BugA"}, 690 BugD{"nested BugD"}, 691 }, 692 } 693 b, err := Marshal(v) 694 if err != nil { 695 t.Fatal("Marshal error:", err) 696 } 697 want := `{}` 698 got := string(b) 699 if got != want { 700 t.Fatalf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 701 } 702} 703 704func TestIssue10281(t *testing.T) { 705 type Foo struct { 706 N Number 707 } 708 x := Foo{Number(`invalid`)} 709 710 if _, err := Marshal(&x); err == nil { 711 t.Fatalf("Marshal error: got nil, want non-nil") 712 } 713} 714 715func TestMarshalErrorAndReuseEncodeState(t *testing.T) { 716 // Disable the GC temporarily to prevent encodeState's in Pool being cleaned away during the test. 717 percent := debug.SetGCPercent(-1) 718 defer debug.SetGCPercent(percent) 719 720 // Trigger an error in Marshal with cyclic data. 721 type Dummy struct { 722 Name string 723 Next *Dummy 724 } 725 dummy := Dummy{Name: "Dummy"} 726 dummy.Next = &dummy 727 if _, err := Marshal(dummy); err == nil { 728 t.Errorf("Marshal error: got nil, want non-nil") 729 } 730 731 type Data struct { 732 A string 733 I int 734 } 735 want := Data{A: "a", I: 1} 736 b, err := Marshal(want) 737 if err != nil { 738 t.Errorf("Marshal error: %v", err) 739 } 740 741 var got Data 742 if err := Unmarshal(b, &got); err != nil { 743 t.Errorf("Unmarshal error: %v", err) 744 } 745 if got != want { 746 t.Errorf("Unmarshal:\n\tgot: %v\n\twant: %v", got, want) 747 } 748} 749 750func TestHTMLEscape(t *testing.T) { 751 var b, want bytes.Buffer 752 m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}` 753 want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`)) 754 HTMLEscape(&b, []byte(m)) 755 if !bytes.Equal(b.Bytes(), want.Bytes()) { 756 t.Errorf("HTMLEscape:\n\tgot: %s\n\twant: %s", b.Bytes(), want.Bytes()) 757 } 758} 759 760// golang.org/issue/8582 761func TestEncodePointerString(t *testing.T) { 762 type stringPointer struct { 763 N *int64 `json:"n,string"` 764 } 765 var n int64 = 42 766 b, err := Marshal(stringPointer{N: &n}) 767 if err != nil { 768 t.Fatalf("Marshal error: %v", err) 769 } 770 if got, want := string(b), `{"n":"42"}`; got != want { 771 t.Fatalf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 772 } 773 var back stringPointer 774 switch err = Unmarshal(b, &back); { 775 case err != nil: 776 t.Fatalf("Unmarshal error: %v", err) 777 case back.N == nil: 778 t.Fatalf("Unmarshal: back.N = nil, want non-nil") 779 case *back.N != 42: 780 t.Fatalf("Unmarshal: *back.N = %d, want 42", *back.N) 781 } 782} 783 784var encodeStringTests = []struct { 785 in string 786 out string 787}{ 788 {"\x00", `"\u0000"`}, 789 {"\x01", `"\u0001"`}, 790 {"\x02", `"\u0002"`}, 791 {"\x03", `"\u0003"`}, 792 {"\x04", `"\u0004"`}, 793 {"\x05", `"\u0005"`}, 794 {"\x06", `"\u0006"`}, 795 {"\x07", `"\u0007"`}, 796 {"\x08", `"\b"`}, 797 {"\x09", `"\t"`}, 798 {"\x0a", `"\n"`}, 799 {"\x0b", `"\u000b"`}, 800 {"\x0c", `"\f"`}, 801 {"\x0d", `"\r"`}, 802 {"\x0e", `"\u000e"`}, 803 {"\x0f", `"\u000f"`}, 804 {"\x10", `"\u0010"`}, 805 {"\x11", `"\u0011"`}, 806 {"\x12", `"\u0012"`}, 807 {"\x13", `"\u0013"`}, 808 {"\x14", `"\u0014"`}, 809 {"\x15", `"\u0015"`}, 810 {"\x16", `"\u0016"`}, 811 {"\x17", `"\u0017"`}, 812 {"\x18", `"\u0018"`}, 813 {"\x19", `"\u0019"`}, 814 {"\x1a", `"\u001a"`}, 815 {"\x1b", `"\u001b"`}, 816 {"\x1c", `"\u001c"`}, 817 {"\x1d", `"\u001d"`}, 818 {"\x1e", `"\u001e"`}, 819 {"\x1f", `"\u001f"`}, 820} 821 822func TestEncodeString(t *testing.T) { 823 for _, tt := range encodeStringTests { 824 b, err := Marshal(tt.in) 825 if err != nil { 826 t.Errorf("Marshal(%q) error: %v", tt.in, err) 827 continue 828 } 829 out := string(b) 830 if out != tt.out { 831 t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out) 832 } 833 } 834} 835 836type jsonbyte byte 837 838func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) } 839 840type textbyte byte 841 842func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) } 843 844type jsonint int 845 846func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) } 847 848type textint int 849 850func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) } 851 852func tenc(format string, a ...any) ([]byte, error) { 853 var buf bytes.Buffer 854 fmt.Fprintf(&buf, format, a...) 855 return buf.Bytes(), nil 856} 857 858type textfloat float64 859 860func (f textfloat) MarshalText() ([]byte, error) { return tenc(`TF:%0.2f`, f) } 861 862// Issue 13783 863func TestEncodeBytekind(t *testing.T) { 864 tests := []struct { 865 CaseName 866 in any 867 want string 868 }{ 869 {Name(""), byte(7), "7"}, 870 {Name(""), jsonbyte(7), `{"JB":7}`}, 871 {Name(""), textbyte(4), `"TB:4"`}, 872 {Name(""), jsonint(5), `{"JI":5}`}, 873 {Name(""), textint(1), `"TI:1"`}, 874 {Name(""), []byte{0, 1}, `"AAE="`}, 875 {Name(""), []jsonbyte{0, 1}, `[{"JB":0},{"JB":1}]`}, 876 {Name(""), [][]jsonbyte{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`}, 877 {Name(""), []textbyte{2, 3}, `["TB:2","TB:3"]`}, 878 {Name(""), []jsonint{5, 4}, `[{"JI":5},{"JI":4}]`}, 879 {Name(""), []textint{9, 3}, `["TI:9","TI:3"]`}, 880 {Name(""), []int{9, 3}, `[9,3]`}, 881 {Name(""), []textfloat{12, 3}, `["TF:12.00","TF:3.00"]`}, 882 } 883 for _, tt := range tests { 884 t.Run(tt.Name, func(t *testing.T) { 885 b, err := Marshal(tt.in) 886 if err != nil { 887 t.Errorf("%s: Marshal error: %v", tt.Where, err) 888 } 889 got, want := string(b), tt.want 890 if got != want { 891 t.Errorf("%s: Marshal:\n\tgot: %s\n\twant: %s", tt.Where, got, want) 892 } 893 }) 894 } 895} 896 897func TestTextMarshalerMapKeysAreSorted(t *testing.T) { 898 got, err := Marshal(map[unmarshalerText]int{ 899 {"x", "y"}: 1, 900 {"y", "x"}: 2, 901 {"a", "z"}: 3, 902 {"z", "a"}: 4, 903 }) 904 if err != nil { 905 t.Fatalf("Marshal error: %v", err) 906 } 907 const want = `{"a:z":3,"x:y":1,"y:x":2,"z:a":4}` 908 if string(got) != want { 909 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 910 } 911} 912 913// https://golang.org/issue/33675 914func TestNilMarshalerTextMapKey(t *testing.T) { 915 got, err := Marshal(map[*unmarshalerText]int{ 916 (*unmarshalerText)(nil): 1, 917 {"A", "B"}: 2, 918 }) 919 if err != nil { 920 t.Fatalf("Marshal error: %v", err) 921 } 922 const want = `{"":1,"A:B":2}` 923 if string(got) != want { 924 t.Errorf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 925 } 926} 927 928var re = regexp.MustCompile 929 930// syntactic checks on form of marshaled floating point numbers. 931var badFloatREs = []*regexp.Regexp{ 932 re(`p`), // no binary exponential notation 933 re(`^\+`), // no leading + sign 934 re(`^-?0[^.]`), // no unnecessary leading zeros 935 re(`^-?\.`), // leading zero required before decimal point 936 re(`\.(e|$)`), // no trailing decimal 937 re(`\.[0-9]+0(e|$)`), // no trailing zero in fraction 938 re(`^-?(0|[0-9]{2,})\..*e`), // exponential notation must have normalized mantissa 939 re(`e[0-9]`), // positive exponent must be signed 940 re(`e[+-]0`), // exponent must not have leading zeros 941 re(`e-[1-6]$`), // not tiny enough for exponential notation 942 re(`e+(.|1.|20)$`), // not big enough for exponential notation 943 re(`^-?0\.0000000`), // too tiny, should use exponential notation 944 re(`^-?[0-9]{22}`), // too big, should use exponential notation 945 re(`[1-9][0-9]{16}[1-9]`), // too many significant digits in integer 946 re(`[1-9][0-9.]{17}[1-9]`), // too many significant digits in decimal 947 // below here for float32 only 948 re(`[1-9][0-9]{8}[1-9]`), // too many significant digits in integer 949 re(`[1-9][0-9.]{9}[1-9]`), // too many significant digits in decimal 950} 951 952func TestMarshalFloat(t *testing.T) { 953 t.Parallel() 954 nfail := 0 955 test := func(f float64, bits int) { 956 vf := any(f) 957 if bits == 32 { 958 f = float64(float32(f)) // round 959 vf = float32(f) 960 } 961 bout, err := Marshal(vf) 962 if err != nil { 963 t.Errorf("Marshal(%T(%g)) error: %v", vf, vf, err) 964 nfail++ 965 return 966 } 967 out := string(bout) 968 969 // result must convert back to the same float 970 g, err := strconv.ParseFloat(out, bits) 971 if err != nil { 972 t.Errorf("ParseFloat(%q) error: %v", out, err) 973 nfail++ 974 return 975 } 976 if f != g || fmt.Sprint(f) != fmt.Sprint(g) { // fmt.Sprint handles ±0 977 t.Errorf("ParseFloat(%q):\n\tgot: %g\n\twant: %g", out, float32(g), vf) 978 nfail++ 979 return 980 } 981 982 bad := badFloatREs 983 if bits == 64 { 984 bad = bad[:len(bad)-2] 985 } 986 for _, re := range bad { 987 if re.MatchString(out) { 988 t.Errorf("Marshal(%T(%g)) = %q; must not match /%s/", vf, vf, out, re) 989 nfail++ 990 return 991 } 992 } 993 } 994 995 var ( 996 bigger = math.Inf(+1) 997 smaller = math.Inf(-1) 998 ) 999 1000 var digits = "1.2345678901234567890123" 1001 for i := len(digits); i >= 2; i-- { 1002 if testing.Short() && i < len(digits)-4 { 1003 break 1004 } 1005 for exp := -30; exp <= 30; exp++ { 1006 for _, sign := range "+-" { 1007 for bits := 32; bits <= 64; bits += 32 { 1008 s := fmt.Sprintf("%c%se%d", sign, digits[:i], exp) 1009 f, err := strconv.ParseFloat(s, bits) 1010 if err != nil { 1011 log.Fatal(err) 1012 } 1013 next := math.Nextafter 1014 if bits == 32 { 1015 next = func(g, h float64) float64 { 1016 return float64(math.Nextafter32(float32(g), float32(h))) 1017 } 1018 } 1019 test(f, bits) 1020 test(next(f, bigger), bits) 1021 test(next(f, smaller), bits) 1022 if nfail > 50 { 1023 t.Fatalf("stopping test early") 1024 } 1025 } 1026 } 1027 } 1028 } 1029 test(0, 64) 1030 test(math.Copysign(0, -1), 64) 1031 test(0, 32) 1032 test(math.Copysign(0, -1), 32) 1033} 1034 1035func TestMarshalRawMessageValue(t *testing.T) { 1036 type ( 1037 T1 struct { 1038 M RawMessage `json:",omitempty"` 1039 } 1040 T2 struct { 1041 M *RawMessage `json:",omitempty"` 1042 } 1043 ) 1044 1045 var ( 1046 rawNil = RawMessage(nil) 1047 rawEmpty = RawMessage([]byte{}) 1048 rawText = RawMessage([]byte(`"foo"`)) 1049 ) 1050 1051 tests := []struct { 1052 CaseName 1053 in any 1054 want string 1055 ok bool 1056 }{ 1057 // Test with nil RawMessage. 1058 {Name(""), rawNil, "null", true}, 1059 {Name(""), &rawNil, "null", true}, 1060 {Name(""), []any{rawNil}, "[null]", true}, 1061 {Name(""), &[]any{rawNil}, "[null]", true}, 1062 {Name(""), []any{&rawNil}, "[null]", true}, 1063 {Name(""), &[]any{&rawNil}, "[null]", true}, 1064 {Name(""), struct{ M RawMessage }{rawNil}, `{"M":null}`, true}, 1065 {Name(""), &struct{ M RawMessage }{rawNil}, `{"M":null}`, true}, 1066 {Name(""), struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true}, 1067 {Name(""), &struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true}, 1068 {Name(""), map[string]any{"M": rawNil}, `{"M":null}`, true}, 1069 {Name(""), &map[string]any{"M": rawNil}, `{"M":null}`, true}, 1070 {Name(""), map[string]any{"M": &rawNil}, `{"M":null}`, true}, 1071 {Name(""), &map[string]any{"M": &rawNil}, `{"M":null}`, true}, 1072 {Name(""), T1{rawNil}, "{}", true}, 1073 {Name(""), T2{&rawNil}, `{"M":null}`, true}, 1074 {Name(""), &T1{rawNil}, "{}", true}, 1075 {Name(""), &T2{&rawNil}, `{"M":null}`, true}, 1076 1077 // Test with empty, but non-nil, RawMessage. 1078 {Name(""), rawEmpty, "", false}, 1079 {Name(""), &rawEmpty, "", false}, 1080 {Name(""), []any{rawEmpty}, "", false}, 1081 {Name(""), &[]any{rawEmpty}, "", false}, 1082 {Name(""), []any{&rawEmpty}, "", false}, 1083 {Name(""), &[]any{&rawEmpty}, "", false}, 1084 {Name(""), struct{ X RawMessage }{rawEmpty}, "", false}, 1085 {Name(""), &struct{ X RawMessage }{rawEmpty}, "", false}, 1086 {Name(""), struct{ X *RawMessage }{&rawEmpty}, "", false}, 1087 {Name(""), &struct{ X *RawMessage }{&rawEmpty}, "", false}, 1088 {Name(""), map[string]any{"nil": rawEmpty}, "", false}, 1089 {Name(""), &map[string]any{"nil": rawEmpty}, "", false}, 1090 {Name(""), map[string]any{"nil": &rawEmpty}, "", false}, 1091 {Name(""), &map[string]any{"nil": &rawEmpty}, "", false}, 1092 {Name(""), T1{rawEmpty}, "{}", true}, 1093 {Name(""), T2{&rawEmpty}, "", false}, 1094 {Name(""), &T1{rawEmpty}, "{}", true}, 1095 {Name(""), &T2{&rawEmpty}, "", false}, 1096 1097 // Test with RawMessage with some text. 1098 // 1099 // The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo". 1100 // This behavior was intentionally changed in Go 1.8. 1101 // See https://golang.org/issues/14493#issuecomment-255857318 1102 {Name(""), rawText, `"foo"`, true}, // Issue6458 1103 {Name(""), &rawText, `"foo"`, true}, 1104 {Name(""), []any{rawText}, `["foo"]`, true}, // Issue6458 1105 {Name(""), &[]any{rawText}, `["foo"]`, true}, // Issue6458 1106 {Name(""), []any{&rawText}, `["foo"]`, true}, 1107 {Name(""), &[]any{&rawText}, `["foo"]`, true}, 1108 {Name(""), struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true}, // Issue6458 1109 {Name(""), &struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true}, 1110 {Name(""), struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true}, 1111 {Name(""), &struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true}, 1112 {Name(""), map[string]any{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458 1113 {Name(""), &map[string]any{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458 1114 {Name(""), map[string]any{"M": &rawText}, `{"M":"foo"}`, true}, 1115 {Name(""), &map[string]any{"M": &rawText}, `{"M":"foo"}`, true}, 1116 {Name(""), T1{rawText}, `{"M":"foo"}`, true}, // Issue6458 1117 {Name(""), T2{&rawText}, `{"M":"foo"}`, true}, 1118 {Name(""), &T1{rawText}, `{"M":"foo"}`, true}, 1119 {Name(""), &T2{&rawText}, `{"M":"foo"}`, true}, 1120 } 1121 1122 for _, tt := range tests { 1123 t.Run(tt.Name, func(t *testing.T) { 1124 b, err := Marshal(tt.in) 1125 if ok := (err == nil); ok != tt.ok { 1126 if err != nil { 1127 t.Errorf("%s: Marshal error: %v", tt.Where, err) 1128 } else { 1129 t.Errorf("%s: Marshal error: got nil, want non-nil", tt.Where) 1130 } 1131 } 1132 if got := string(b); got != tt.want { 1133 t.Errorf("%s: Marshal:\n\tinput: %#v\n\tgot: %s\n\twant: %s", tt.Where, tt.in, got, tt.want) 1134 } 1135 }) 1136 } 1137} 1138 1139type marshalPanic struct{} 1140 1141func (marshalPanic) MarshalJSON() ([]byte, error) { panic(0xdead) } 1142 1143func TestMarshalPanic(t *testing.T) { 1144 defer func() { 1145 if got := recover(); !reflect.DeepEqual(got, 0xdead) { 1146 t.Errorf("panic() = (%T)(%v), want 0xdead", got, got) 1147 } 1148 }() 1149 Marshal(&marshalPanic{}) 1150 t.Error("Marshal should have panicked") 1151} 1152 1153func TestMarshalUncommonFieldNames(t *testing.T) { 1154 v := struct { 1155 A0, À, Aβ int 1156 }{} 1157 b, err := Marshal(v) 1158 if err != nil { 1159 t.Fatal("Marshal error:", err) 1160 } 1161 want := `{"A0":0,"À":0,"Aβ":0}` 1162 got := string(b) 1163 if got != want { 1164 t.Fatalf("Marshal:\n\tgot: %s\n\twant: %s", got, want) 1165 } 1166} 1167 1168func TestMarshalerError(t *testing.T) { 1169 s := "test variable" 1170 st := reflect.TypeOf(s) 1171 const errText = "json: test error" 1172 1173 tests := []struct { 1174 CaseName 1175 err *MarshalerError 1176 want string 1177 }{{ 1178 Name(""), 1179 &MarshalerError{st, fmt.Errorf(errText), ""}, 1180 "json: error calling MarshalJSON for type " + st.String() + ": " + errText, 1181 }, { 1182 Name(""), 1183 &MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"}, 1184 "json: error calling TestMarshalerError for type " + st.String() + ": " + errText, 1185 }} 1186 1187 for _, tt := range tests { 1188 t.Run(tt.Name, func(t *testing.T) { 1189 got := tt.err.Error() 1190 if got != tt.want { 1191 t.Errorf("%s: Error:\n\tgot: %s\n\twant: %s", tt.Where, got, tt.want) 1192 } 1193 }) 1194 } 1195} 1196 1197type marshaledValue string 1198 1199func (v marshaledValue) MarshalJSON() ([]byte, error) { 1200 return []byte(v), nil 1201} 1202 1203func TestIssue63379(t *testing.T) { 1204 for _, v := range []string{ 1205 "[]<", 1206 "[]>", 1207 "[]&", 1208 "[]\u2028", 1209 "[]\u2029", 1210 "{}<", 1211 "{}>", 1212 "{}&", 1213 "{}\u2028", 1214 "{}\u2029", 1215 } { 1216 _, err := Marshal(marshaledValue(v)) 1217 if err == nil { 1218 t.Errorf("expected error for %q", v) 1219 } 1220 } 1221} 1222