github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/encoding/json/decode_test.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package json 6 7 import ( 8 "bytes" 9 "encoding" 10 "fmt" 11 "image" 12 "reflect" 13 "strings" 14 "testing" 15 "time" 16 ) 17 18 type T struct { 19 X string 20 Y int 21 Z int `json:"-"` 22 } 23 24 type U struct { 25 Alphabet string `json:"alpha"` 26 } 27 28 type V struct { 29 F1 interface{} 30 F2 int32 31 F3 Number 32 } 33 34 // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and 35 // without UseNumber 36 var ifaceNumAsFloat64 = map[string]interface{}{ 37 "k1": float64(1), 38 "k2": "s", 39 "k3": []interface{}{float64(1), float64(2.0), float64(3e-3)}, 40 "k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)}, 41 } 42 43 var ifaceNumAsNumber = map[string]interface{}{ 44 "k1": Number("1"), 45 "k2": "s", 46 "k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")}, 47 "k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")}, 48 } 49 50 type tx struct { 51 x int 52 } 53 54 // A type that can unmarshal itself. 55 56 type unmarshaler struct { 57 T bool 58 } 59 60 func (u *unmarshaler) UnmarshalJSON(b []byte) error { 61 *u = unmarshaler{true} // All we need to see that UnmarshalJSON is called. 62 return nil 63 } 64 65 type ustruct struct { 66 M unmarshaler 67 } 68 69 type unmarshalerText struct { 70 T bool 71 } 72 73 // needed for re-marshaling tests 74 func (u *unmarshalerText) MarshalText() ([]byte, error) { 75 return []byte(""), nil 76 } 77 78 func (u *unmarshalerText) UnmarshalText(b []byte) error { 79 *u = unmarshalerText{true} // All we need to see that UnmarshalText is called. 80 return nil 81 } 82 83 var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil) 84 85 type ustructText struct { 86 M unmarshalerText 87 } 88 89 var ( 90 um0, um1 unmarshaler // target2 of unmarshaling 91 ump = &um1 92 umtrue = unmarshaler{true} 93 umslice = []unmarshaler{{true}} 94 umslicep = new([]unmarshaler) 95 umstruct = ustruct{unmarshaler{true}} 96 97 um0T, um1T unmarshalerText // target2 of unmarshaling 98 umpT = &um1T 99 umtrueT = unmarshalerText{true} 100 umsliceT = []unmarshalerText{{true}} 101 umslicepT = new([]unmarshalerText) 102 umstructT = ustructText{unmarshalerText{true}} 103 ) 104 105 // Test data structures for anonymous fields. 106 107 type Point struct { 108 Z int 109 } 110 111 type Top struct { 112 Level0 int 113 Embed0 114 *Embed0a 115 *Embed0b `json:"e,omitempty"` // treated as named 116 Embed0c `json:"-"` // ignored 117 Loop 118 Embed0p // has Point with X, Y, used 119 Embed0q // has Point with Z, used 120 } 121 122 type Embed0 struct { 123 Level1a int // overridden by Embed0a's Level1a with json tag 124 Level1b int // used because Embed0a's Level1b is renamed 125 Level1c int // used because Embed0a's Level1c is ignored 126 Level1d int // annihilated by Embed0a's Level1d 127 Level1e int `json:"x"` // annihilated by Embed0a.Level1e 128 } 129 130 type Embed0a struct { 131 Level1a int `json:"Level1a,omitempty"` 132 Level1b int `json:"LEVEL1B,omitempty"` 133 Level1c int `json:"-"` 134 Level1d int // annihilated by Embed0's Level1d 135 Level1f int `json:"x"` // annihilated by Embed0's Level1e 136 } 137 138 type Embed0b Embed0 139 140 type Embed0c Embed0 141 142 type Embed0p struct { 143 image.Point 144 } 145 146 type Embed0q struct { 147 Point 148 } 149 150 type Loop struct { 151 Loop1 int `json:",omitempty"` 152 Loop2 int `json:",omitempty"` 153 *Loop 154 } 155 156 // From reflect test: 157 // The X in S6 and S7 annihilate, but they also block the X in S8.S9. 158 type S5 struct { 159 S6 160 S7 161 S8 162 } 163 164 type S6 struct { 165 X int 166 } 167 168 type S7 S6 169 170 type S8 struct { 171 S9 172 } 173 174 type S9 struct { 175 X int 176 Y int 177 } 178 179 // From reflect test: 180 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9. 181 type S10 struct { 182 S11 183 S12 184 S13 185 } 186 187 type S11 struct { 188 S6 189 } 190 191 type S12 struct { 192 S6 193 } 194 195 type S13 struct { 196 S8 197 } 198 199 type unmarshalTest struct { 200 in string 201 ptr interface{} 202 out interface{} 203 err error 204 useNumber bool 205 } 206 207 type Ambig struct { 208 // Given "hello", the first match should win. 209 First int `json:"HELLO"` 210 Second int `json:"Hello"` 211 } 212 213 type XYZ struct { 214 X interface{} 215 Y interface{} 216 Z interface{} 217 } 218 219 var unmarshalTests = []unmarshalTest{ 220 // basic types 221 {in: `true`, ptr: new(bool), out: true}, 222 {in: `1`, ptr: new(int), out: 1}, 223 {in: `1.2`, ptr: new(float64), out: 1.2}, 224 {in: `-5`, ptr: new(int16), out: int16(-5)}, 225 {in: `2`, ptr: new(Number), out: Number("2"), useNumber: true}, 226 {in: `2`, ptr: new(Number), out: Number("2")}, 227 {in: `2`, ptr: new(interface{}), out: float64(2.0)}, 228 {in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true}, 229 {in: `"a\u1234"`, ptr: new(string), out: "a\u1234"}, 230 {in: `"http:\/\/"`, ptr: new(string), out: "http://"}, 231 {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"}, 232 {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, 233 {in: "null", ptr: new(interface{}), out: nil}, 234 {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}}, 235 {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, 236 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, 237 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true}, 238 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64}, 239 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true}, 240 241 // raw values with whitespace 242 {in: "\n true ", ptr: new(bool), out: true}, 243 {in: "\t 1 ", ptr: new(int), out: 1}, 244 {in: "\r 1.2 ", ptr: new(float64), out: 1.2}, 245 {in: "\t -5 \n", ptr: new(int16), out: int16(-5)}, 246 {in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"}, 247 248 // Z has a "-" tag. 249 {in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}}, 250 251 {in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 252 {in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 253 {in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}}, 254 255 // syntax errors 256 {in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}}, 257 {in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}}, 258 {in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true}, 259 260 // raw value errors 261 {in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 262 {in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}}, 263 {in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 264 {in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}}, 265 {in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 266 {in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}}, 267 {in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 268 {in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}}, 269 270 // array tests 271 {in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}}, 272 {in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}}, 273 {in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}}, 274 275 // empty array to interface test 276 {in: `[]`, ptr: new([]interface{}), out: []interface{}{}}, 277 {in: `null`, ptr: new([]interface{}), out: []interface{}(nil)}, 278 {in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}}, 279 {in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}}, 280 281 // composite tests 282 {in: allValueIndent, ptr: new(All), out: allValue}, 283 {in: allValueCompact, ptr: new(All), out: allValue}, 284 {in: allValueIndent, ptr: new(*All), out: &allValue}, 285 {in: allValueCompact, ptr: new(*All), out: &allValue}, 286 {in: pallValueIndent, ptr: new(All), out: pallValue}, 287 {in: pallValueCompact, ptr: new(All), out: pallValue}, 288 {in: pallValueIndent, ptr: new(*All), out: &pallValue}, 289 {in: pallValueCompact, ptr: new(*All), out: &pallValue}, 290 291 // unmarshal interface test 292 {in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called 293 {in: `{"T":false}`, ptr: &ump, out: &umtrue}, 294 {in: `[{"T":false}]`, ptr: &umslice, out: umslice}, 295 {in: `[{"T":false}]`, ptr: &umslicep, out: &umslice}, 296 {in: `{"M":{"T":false}}`, ptr: &umstruct, out: umstruct}, 297 298 // UnmarshalText interface test 299 {in: `"X"`, ptr: &um0T, out: umtrueT}, // use "false" so test will fail if custom unmarshaler is not called 300 {in: `"X"`, ptr: &umpT, out: &umtrueT}, 301 {in: `["X"]`, ptr: &umsliceT, out: umsliceT}, 302 {in: `["X"]`, ptr: &umslicepT, out: &umsliceT}, 303 {in: `{"M":"X"}`, ptr: &umstructT, out: umstructT}, 304 305 { 306 in: `{ 307 "Level0": 1, 308 "Level1b": 2, 309 "Level1c": 3, 310 "x": 4, 311 "Level1a": 5, 312 "LEVEL1B": 6, 313 "e": { 314 "Level1a": 8, 315 "Level1b": 9, 316 "Level1c": 10, 317 "Level1d": 11, 318 "x": 12 319 }, 320 "Loop1": 13, 321 "Loop2": 14, 322 "X": 15, 323 "Y": 16, 324 "Z": 17 325 }`, 326 ptr: new(Top), 327 out: Top{ 328 Level0: 1, 329 Embed0: Embed0{ 330 Level1b: 2, 331 Level1c: 3, 332 }, 333 Embed0a: &Embed0a{ 334 Level1a: 5, 335 Level1b: 6, 336 }, 337 Embed0b: &Embed0b{ 338 Level1a: 8, 339 Level1b: 9, 340 Level1c: 10, 341 Level1d: 11, 342 Level1e: 12, 343 }, 344 Loop: Loop{ 345 Loop1: 13, 346 Loop2: 14, 347 }, 348 Embed0p: Embed0p{ 349 Point: image.Point{X: 15, Y: 16}, 350 }, 351 Embed0q: Embed0q{ 352 Point: Point{Z: 17}, 353 }, 354 }, 355 }, 356 { 357 in: `{"hello": 1}`, 358 ptr: new(Ambig), 359 out: Ambig{First: 1}, 360 }, 361 362 { 363 in: `{"X": 1,"Y":2}`, 364 ptr: new(S5), 365 out: S5{S8: S8{S9: S9{Y: 2}}}, 366 }, 367 { 368 in: `{"X": 1,"Y":2}`, 369 ptr: new(S10), 370 out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}}, 371 }, 372 373 // invalid UTF-8 is coerced to valid UTF-8. 374 { 375 in: "\"hello\xffworld\"", 376 ptr: new(string), 377 out: "hello\ufffdworld", 378 }, 379 { 380 in: "\"hello\xc2\xc2world\"", 381 ptr: new(string), 382 out: "hello\ufffd\ufffdworld", 383 }, 384 { 385 in: "\"hello\xc2\xffworld\"", 386 ptr: new(string), 387 out: "hello\ufffd\ufffdworld", 388 }, 389 { 390 in: "\"hello\\ud800world\"", 391 ptr: new(string), 392 out: "hello\ufffdworld", 393 }, 394 { 395 in: "\"hello\\ud800\\ud800world\"", 396 ptr: new(string), 397 out: "hello\ufffd\ufffdworld", 398 }, 399 { 400 in: "\"hello\\ud800\\ud800world\"", 401 ptr: new(string), 402 out: "hello\ufffd\ufffdworld", 403 }, 404 { 405 in: "\"hello\xed\xa0\x80\xed\xb0\x80world\"", 406 ptr: new(string), 407 out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld", 408 }, 409 410 // issue 8305 411 { 412 in: `{"2009-11-10T23:00:00Z": "hello world"}`, 413 ptr: &map[time.Time]string{}, 414 err: &UnmarshalTypeError{"object", reflect.TypeOf(map[time.Time]string{})}, 415 }, 416 } 417 418 func TestMarshal(t *testing.T) { 419 b, err := Marshal(allValue) 420 if err != nil { 421 t.Fatalf("Marshal allValue: %v", err) 422 } 423 if string(b) != allValueCompact { 424 t.Errorf("Marshal allValueCompact") 425 diff(t, b, []byte(allValueCompact)) 426 return 427 } 428 429 b, err = Marshal(pallValue) 430 if err != nil { 431 t.Fatalf("Marshal pallValue: %v", err) 432 } 433 if string(b) != pallValueCompact { 434 t.Errorf("Marshal pallValueCompact") 435 diff(t, b, []byte(pallValueCompact)) 436 return 437 } 438 } 439 440 var badUTF8 = []struct { 441 in, out string 442 }{ 443 {"hello\xffworld", `"hello\ufffdworld"`}, 444 {"", `""`}, 445 {"\xff", `"\ufffd"`}, 446 {"\xff\xff", `"\ufffd\ufffd"`}, 447 {"a\xffb", `"a\ufffdb"`}, 448 {"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`}, 449 } 450 451 func TestMarshalBadUTF8(t *testing.T) { 452 for _, tt := range badUTF8 { 453 b, err := Marshal(tt.in) 454 if string(b) != tt.out || err != nil { 455 t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out) 456 } 457 } 458 } 459 460 func TestMarshalNumberZeroVal(t *testing.T) { 461 var n Number 462 out, err := Marshal(n) 463 if err != nil { 464 t.Fatal(err) 465 } 466 outStr := string(out) 467 if outStr != "0" { 468 t.Fatalf("Invalid zero val for Number: %q", outStr) 469 } 470 } 471 472 func TestMarshalEmbeds(t *testing.T) { 473 top := &Top{ 474 Level0: 1, 475 Embed0: Embed0{ 476 Level1b: 2, 477 Level1c: 3, 478 }, 479 Embed0a: &Embed0a{ 480 Level1a: 5, 481 Level1b: 6, 482 }, 483 Embed0b: &Embed0b{ 484 Level1a: 8, 485 Level1b: 9, 486 Level1c: 10, 487 Level1d: 11, 488 Level1e: 12, 489 }, 490 Loop: Loop{ 491 Loop1: 13, 492 Loop2: 14, 493 }, 494 Embed0p: Embed0p{ 495 Point: image.Point{X: 15, Y: 16}, 496 }, 497 Embed0q: Embed0q{ 498 Point: Point{Z: 17}, 499 }, 500 } 501 b, err := Marshal(top) 502 if err != nil { 503 t.Fatal(err) 504 } 505 want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}" 506 if string(b) != want { 507 t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want) 508 } 509 } 510 511 func TestUnmarshal(t *testing.T) { 512 for i, tt := range unmarshalTests { 513 var scan scanner 514 in := []byte(tt.in) 515 if err := checkValid(in, &scan); err != nil { 516 if !reflect.DeepEqual(err, tt.err) { 517 t.Errorf("#%d: checkValid: %#v", i, err) 518 continue 519 } 520 } 521 if tt.ptr == nil { 522 continue 523 } 524 525 // v = new(right-type) 526 v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 527 dec := NewDecoder(bytes.NewReader(in)) 528 if tt.useNumber { 529 dec.UseNumber() 530 } 531 if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) { 532 t.Errorf("#%d: %v, want %v", i, err, tt.err) 533 continue 534 } else if err != nil { 535 continue 536 } 537 if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { 538 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) 539 data, _ := Marshal(v.Elem().Interface()) 540 println(string(data)) 541 data, _ = Marshal(tt.out) 542 println(string(data)) 543 continue 544 } 545 546 // Check round trip. 547 if tt.err == nil { 548 enc, err := Marshal(v.Interface()) 549 if err != nil { 550 t.Errorf("#%d: error re-marshaling: %v", i, err) 551 continue 552 } 553 vv := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 554 dec = NewDecoder(bytes.NewReader(enc)) 555 if tt.useNumber { 556 dec.UseNumber() 557 } 558 if err := dec.Decode(vv.Interface()); err != nil { 559 t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err) 560 continue 561 } 562 if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) { 563 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface()) 564 t.Errorf(" In: %q", strings.Map(noSpace, string(in))) 565 t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc))) 566 continue 567 } 568 } 569 } 570 } 571 572 func TestUnmarshalMarshal(t *testing.T) { 573 initBig() 574 var v interface{} 575 if err := Unmarshal(jsonBig, &v); err != nil { 576 t.Fatalf("Unmarshal: %v", err) 577 } 578 b, err := Marshal(v) 579 if err != nil { 580 t.Fatalf("Marshal: %v", err) 581 } 582 if !bytes.Equal(jsonBig, b) { 583 t.Errorf("Marshal jsonBig") 584 diff(t, b, jsonBig) 585 return 586 } 587 } 588 589 var numberTests = []struct { 590 in string 591 i int64 592 intErr string 593 f float64 594 floatErr string 595 }{ 596 {in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1}, 597 {in: "-12", i: -12, f: -12.0}, 598 {in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"}, 599 } 600 601 // Independent of Decode, basic coverage of the accessors in Number 602 func TestNumberAccessors(t *testing.T) { 603 for _, tt := range numberTests { 604 n := Number(tt.in) 605 if s := n.String(); s != tt.in { 606 t.Errorf("Number(%q).String() is %q", tt.in, s) 607 } 608 if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i { 609 t.Errorf("Number(%q).Int64() is %d", tt.in, i) 610 } else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) { 611 t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err) 612 } 613 if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f { 614 t.Errorf("Number(%q).Float64() is %g", tt.in, f) 615 } else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) { 616 t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err) 617 } 618 } 619 } 620 621 func TestLargeByteSlice(t *testing.T) { 622 s0 := make([]byte, 2000) 623 for i := range s0 { 624 s0[i] = byte(i) 625 } 626 b, err := Marshal(s0) 627 if err != nil { 628 t.Fatalf("Marshal: %v", err) 629 } 630 var s1 []byte 631 if err := Unmarshal(b, &s1); err != nil { 632 t.Fatalf("Unmarshal: %v", err) 633 } 634 if !bytes.Equal(s0, s1) { 635 t.Errorf("Marshal large byte slice") 636 diff(t, s0, s1) 637 } 638 } 639 640 type Xint struct { 641 X int 642 } 643 644 func TestUnmarshalInterface(t *testing.T) { 645 var xint Xint 646 var i interface{} = &xint 647 if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil { 648 t.Fatalf("Unmarshal: %v", err) 649 } 650 if xint.X != 1 { 651 t.Fatalf("Did not write to xint") 652 } 653 } 654 655 func TestUnmarshalPtrPtr(t *testing.T) { 656 var xint Xint 657 pxint := &xint 658 if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil { 659 t.Fatalf("Unmarshal: %v", err) 660 } 661 if xint.X != 1 { 662 t.Fatalf("Did not write to xint") 663 } 664 } 665 666 func TestEscape(t *testing.T) { 667 const input = `"foobar"<html>` + " [\u2028 \u2029]" 668 const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"` 669 b, err := Marshal(input) 670 if err != nil { 671 t.Fatalf("Marshal error: %v", err) 672 } 673 if s := string(b); s != expected { 674 t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected) 675 } 676 } 677 678 // WrongString is a struct that's misusing the ,string modifier. 679 type WrongString struct { 680 Message string `json:"result,string"` 681 } 682 683 type wrongStringTest struct { 684 in, err string 685 } 686 687 var wrongStringTests = []wrongStringTest{ 688 {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`}, 689 {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`}, 690 {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`}, 691 } 692 693 // If people misuse the ,string modifier, the error message should be 694 // helpful, telling the user that they're doing it wrong. 695 func TestErrorMessageFromMisusedString(t *testing.T) { 696 for n, tt := range wrongStringTests { 697 r := strings.NewReader(tt.in) 698 var s WrongString 699 err := NewDecoder(r).Decode(&s) 700 got := fmt.Sprintf("%v", err) 701 if got != tt.err { 702 t.Errorf("%d. got err = %q, want %q", n, got, tt.err) 703 } 704 } 705 } 706 707 func noSpace(c rune) rune { 708 if isSpace(c) { 709 return -1 710 } 711 return c 712 } 713 714 type All struct { 715 Bool bool 716 Int int 717 Int8 int8 718 Int16 int16 719 Int32 int32 720 Int64 int64 721 Uint uint 722 Uint8 uint8 723 Uint16 uint16 724 Uint32 uint32 725 Uint64 uint64 726 Uintptr uintptr 727 Float32 float32 728 Float64 float64 729 730 Foo string `json:"bar"` 731 Foo2 string `json:"bar2,dummyopt"` 732 733 IntStr int64 `json:",string"` 734 735 PBool *bool 736 PInt *int 737 PInt8 *int8 738 PInt16 *int16 739 PInt32 *int32 740 PInt64 *int64 741 PUint *uint 742 PUint8 *uint8 743 PUint16 *uint16 744 PUint32 *uint32 745 PUint64 *uint64 746 PUintptr *uintptr 747 PFloat32 *float32 748 PFloat64 *float64 749 750 String string 751 PString *string 752 753 Map map[string]Small 754 MapP map[string]*Small 755 PMap *map[string]Small 756 PMapP *map[string]*Small 757 758 EmptyMap map[string]Small 759 NilMap map[string]Small 760 761 Slice []Small 762 SliceP []*Small 763 PSlice *[]Small 764 PSliceP *[]*Small 765 766 EmptySlice []Small 767 NilSlice []Small 768 769 StringSlice []string 770 ByteSlice []byte 771 772 Small Small 773 PSmall *Small 774 PPSmall **Small 775 776 Interface interface{} 777 PInterface *interface{} 778 779 unexported int 780 } 781 782 type Small struct { 783 Tag string 784 } 785 786 var allValue = All{ 787 Bool: true, 788 Int: 2, 789 Int8: 3, 790 Int16: 4, 791 Int32: 5, 792 Int64: 6, 793 Uint: 7, 794 Uint8: 8, 795 Uint16: 9, 796 Uint32: 10, 797 Uint64: 11, 798 Uintptr: 12, 799 Float32: 14.1, 800 Float64: 15.1, 801 Foo: "foo", 802 Foo2: "foo2", 803 IntStr: 42, 804 String: "16", 805 Map: map[string]Small{ 806 "17": {Tag: "tag17"}, 807 "18": {Tag: "tag18"}, 808 }, 809 MapP: map[string]*Small{ 810 "19": {Tag: "tag19"}, 811 "20": nil, 812 }, 813 EmptyMap: map[string]Small{}, 814 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, 815 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, 816 EmptySlice: []Small{}, 817 StringSlice: []string{"str24", "str25", "str26"}, 818 ByteSlice: []byte{27, 28, 29}, 819 Small: Small{Tag: "tag30"}, 820 PSmall: &Small{Tag: "tag31"}, 821 Interface: 5.2, 822 } 823 824 var pallValue = All{ 825 PBool: &allValue.Bool, 826 PInt: &allValue.Int, 827 PInt8: &allValue.Int8, 828 PInt16: &allValue.Int16, 829 PInt32: &allValue.Int32, 830 PInt64: &allValue.Int64, 831 PUint: &allValue.Uint, 832 PUint8: &allValue.Uint8, 833 PUint16: &allValue.Uint16, 834 PUint32: &allValue.Uint32, 835 PUint64: &allValue.Uint64, 836 PUintptr: &allValue.Uintptr, 837 PFloat32: &allValue.Float32, 838 PFloat64: &allValue.Float64, 839 PString: &allValue.String, 840 PMap: &allValue.Map, 841 PMapP: &allValue.MapP, 842 PSlice: &allValue.Slice, 843 PSliceP: &allValue.SliceP, 844 PPSmall: &allValue.PSmall, 845 PInterface: &allValue.Interface, 846 } 847 848 var allValueIndent = `{ 849 "Bool": true, 850 "Int": 2, 851 "Int8": 3, 852 "Int16": 4, 853 "Int32": 5, 854 "Int64": 6, 855 "Uint": 7, 856 "Uint8": 8, 857 "Uint16": 9, 858 "Uint32": 10, 859 "Uint64": 11, 860 "Uintptr": 12, 861 "Float32": 14.1, 862 "Float64": 15.1, 863 "bar": "foo", 864 "bar2": "foo2", 865 "IntStr": "42", 866 "PBool": null, 867 "PInt": null, 868 "PInt8": null, 869 "PInt16": null, 870 "PInt32": null, 871 "PInt64": null, 872 "PUint": null, 873 "PUint8": null, 874 "PUint16": null, 875 "PUint32": null, 876 "PUint64": null, 877 "PUintptr": null, 878 "PFloat32": null, 879 "PFloat64": null, 880 "String": "16", 881 "PString": null, 882 "Map": { 883 "17": { 884 "Tag": "tag17" 885 }, 886 "18": { 887 "Tag": "tag18" 888 } 889 }, 890 "MapP": { 891 "19": { 892 "Tag": "tag19" 893 }, 894 "20": null 895 }, 896 "PMap": null, 897 "PMapP": null, 898 "EmptyMap": {}, 899 "NilMap": null, 900 "Slice": [ 901 { 902 "Tag": "tag20" 903 }, 904 { 905 "Tag": "tag21" 906 } 907 ], 908 "SliceP": [ 909 { 910 "Tag": "tag22" 911 }, 912 null, 913 { 914 "Tag": "tag23" 915 } 916 ], 917 "PSlice": null, 918 "PSliceP": null, 919 "EmptySlice": [], 920 "NilSlice": null, 921 "StringSlice": [ 922 "str24", 923 "str25", 924 "str26" 925 ], 926 "ByteSlice": "Gxwd", 927 "Small": { 928 "Tag": "tag30" 929 }, 930 "PSmall": { 931 "Tag": "tag31" 932 }, 933 "PPSmall": null, 934 "Interface": 5.2, 935 "PInterface": null 936 }` 937 938 var allValueCompact = strings.Map(noSpace, allValueIndent) 939 940 var pallValueIndent = `{ 941 "Bool": false, 942 "Int": 0, 943 "Int8": 0, 944 "Int16": 0, 945 "Int32": 0, 946 "Int64": 0, 947 "Uint": 0, 948 "Uint8": 0, 949 "Uint16": 0, 950 "Uint32": 0, 951 "Uint64": 0, 952 "Uintptr": 0, 953 "Float32": 0, 954 "Float64": 0, 955 "bar": "", 956 "bar2": "", 957 "IntStr": "0", 958 "PBool": true, 959 "PInt": 2, 960 "PInt8": 3, 961 "PInt16": 4, 962 "PInt32": 5, 963 "PInt64": 6, 964 "PUint": 7, 965 "PUint8": 8, 966 "PUint16": 9, 967 "PUint32": 10, 968 "PUint64": 11, 969 "PUintptr": 12, 970 "PFloat32": 14.1, 971 "PFloat64": 15.1, 972 "String": "", 973 "PString": "16", 974 "Map": null, 975 "MapP": null, 976 "PMap": { 977 "17": { 978 "Tag": "tag17" 979 }, 980 "18": { 981 "Tag": "tag18" 982 } 983 }, 984 "PMapP": { 985 "19": { 986 "Tag": "tag19" 987 }, 988 "20": null 989 }, 990 "EmptyMap": null, 991 "NilMap": null, 992 "Slice": null, 993 "SliceP": null, 994 "PSlice": [ 995 { 996 "Tag": "tag20" 997 }, 998 { 999 "Tag": "tag21" 1000 } 1001 ], 1002 "PSliceP": [ 1003 { 1004 "Tag": "tag22" 1005 }, 1006 null, 1007 { 1008 "Tag": "tag23" 1009 } 1010 ], 1011 "EmptySlice": null, 1012 "NilSlice": null, 1013 "StringSlice": null, 1014 "ByteSlice": null, 1015 "Small": { 1016 "Tag": "" 1017 }, 1018 "PSmall": null, 1019 "PPSmall": { 1020 "Tag": "tag31" 1021 }, 1022 "Interface": null, 1023 "PInterface": 5.2 1024 }` 1025 1026 var pallValueCompact = strings.Map(noSpace, pallValueIndent) 1027 1028 func TestRefUnmarshal(t *testing.T) { 1029 type S struct { 1030 // Ref is defined in encode_test.go. 1031 R0 Ref 1032 R1 *Ref 1033 R2 RefText 1034 R3 *RefText 1035 } 1036 want := S{ 1037 R0: 12, 1038 R1: new(Ref), 1039 R2: 13, 1040 R3: new(RefText), 1041 } 1042 *want.R1 = 12 1043 *want.R3 = 13 1044 1045 var got S 1046 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil { 1047 t.Fatalf("Unmarshal: %v", err) 1048 } 1049 if !reflect.DeepEqual(got, want) { 1050 t.Errorf("got %+v, want %+v", got, want) 1051 } 1052 } 1053 1054 // Test that the empty string doesn't panic decoding when ,string is specified 1055 // Issue 3450 1056 func TestEmptyString(t *testing.T) { 1057 type T2 struct { 1058 Number1 int `json:",string"` 1059 Number2 int `json:",string"` 1060 } 1061 data := `{"Number1":"1", "Number2":""}` 1062 dec := NewDecoder(strings.NewReader(data)) 1063 var t2 T2 1064 err := dec.Decode(&t2) 1065 if err == nil { 1066 t.Fatal("Decode: did not return error") 1067 } 1068 if t2.Number1 != 1 { 1069 t.Fatal("Decode: did not set Number1") 1070 } 1071 } 1072 1073 // Test that a null for ,string is not replaced with the previous quoted string (issue 7046). 1074 // It should also not be an error (issue 2540, issue 8587). 1075 func TestNullString(t *testing.T) { 1076 type T struct { 1077 A int `json:",string"` 1078 B int `json:",string"` 1079 C *int `json:",string"` 1080 } 1081 data := []byte(`{"A": "1", "B": null, "C": null}`) 1082 var s T 1083 s.B = 1 1084 s.C = new(int) 1085 *s.C = 2 1086 err := Unmarshal(data, &s) 1087 if err != nil { 1088 t.Fatalf("Unmarshal: %v") 1089 } 1090 if s.B != 1 || s.C != nil { 1091 t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C) 1092 } 1093 } 1094 1095 func intp(x int) *int { 1096 p := new(int) 1097 *p = x 1098 return p 1099 } 1100 1101 func intpp(x *int) **int { 1102 pp := new(*int) 1103 *pp = x 1104 return pp 1105 } 1106 1107 var interfaceSetTests = []struct { 1108 pre interface{} 1109 json string 1110 post interface{} 1111 }{ 1112 {"foo", `"bar"`, "bar"}, 1113 {"foo", `2`, 2.0}, 1114 {"foo", `true`, true}, 1115 {"foo", `null`, nil}, 1116 1117 {nil, `null`, nil}, 1118 {new(int), `null`, nil}, 1119 {(*int)(nil), `null`, nil}, 1120 {new(*int), `null`, new(*int)}, 1121 {(**int)(nil), `null`, nil}, 1122 {intp(1), `null`, nil}, 1123 {intpp(nil), `null`, intpp(nil)}, 1124 {intpp(intp(1)), `null`, intpp(nil)}, 1125 } 1126 1127 func TestInterfaceSet(t *testing.T) { 1128 for _, tt := range interfaceSetTests { 1129 b := struct{ X interface{} }{tt.pre} 1130 blob := `{"X":` + tt.json + `}` 1131 if err := Unmarshal([]byte(blob), &b); err != nil { 1132 t.Errorf("Unmarshal %#q: %v", blob, err) 1133 continue 1134 } 1135 if !reflect.DeepEqual(b.X, tt.post) { 1136 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post) 1137 } 1138 } 1139 } 1140 1141 // JSON null values should be ignored for primitives and string values instead of resulting in an error. 1142 // Issue 2540 1143 func TestUnmarshalNulls(t *testing.T) { 1144 jsonData := []byte(`{ 1145 "Bool" : null, 1146 "Int" : null, 1147 "Int8" : null, 1148 "Int16" : null, 1149 "Int32" : null, 1150 "Int64" : null, 1151 "Uint" : null, 1152 "Uint8" : null, 1153 "Uint16" : null, 1154 "Uint32" : null, 1155 "Uint64" : null, 1156 "Float32" : null, 1157 "Float64" : null, 1158 "String" : null}`) 1159 1160 nulls := All{ 1161 Bool: true, 1162 Int: 2, 1163 Int8: 3, 1164 Int16: 4, 1165 Int32: 5, 1166 Int64: 6, 1167 Uint: 7, 1168 Uint8: 8, 1169 Uint16: 9, 1170 Uint32: 10, 1171 Uint64: 11, 1172 Float32: 12.1, 1173 Float64: 13.1, 1174 String: "14"} 1175 1176 err := Unmarshal(jsonData, &nulls) 1177 if err != nil { 1178 t.Errorf("Unmarshal of null values failed: %v", err) 1179 } 1180 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 || 1181 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 || 1182 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" { 1183 1184 t.Errorf("Unmarshal of null values affected primitives") 1185 } 1186 } 1187 1188 func TestStringKind(t *testing.T) { 1189 type stringKind string 1190 1191 var m1, m2 map[stringKind]int 1192 m1 = map[stringKind]int{ 1193 "foo": 42, 1194 } 1195 1196 data, err := Marshal(m1) 1197 if err != nil { 1198 t.Errorf("Unexpected error marshalling: %v", err) 1199 } 1200 1201 err = Unmarshal(data, &m2) 1202 if err != nil { 1203 t.Errorf("Unexpected error unmarshalling: %v", err) 1204 } 1205 1206 if !reflect.DeepEqual(m1, m2) { 1207 t.Error("Items should be equal after encoding and then decoding") 1208 } 1209 1210 } 1211 1212 var decodeTypeErrorTests = []struct { 1213 dest interface{} 1214 src string 1215 }{ 1216 {new(string), `{"user": "name"}`}, // issue 4628. 1217 {new(error), `{}`}, // issue 4222 1218 {new(error), `[]`}, 1219 {new(error), `""`}, 1220 {new(error), `123`}, 1221 {new(error), `true`}, 1222 } 1223 1224 func TestUnmarshalTypeError(t *testing.T) { 1225 for _, item := range decodeTypeErrorTests { 1226 err := Unmarshal([]byte(item.src), item.dest) 1227 if _, ok := err.(*UnmarshalTypeError); !ok { 1228 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", 1229 item.src, item.dest, err) 1230 } 1231 } 1232 } 1233 1234 var unmarshalSyntaxTests = []string{ 1235 "tru", 1236 "fals", 1237 "nul", 1238 "123e", 1239 `"hello`, 1240 `[1,2,3`, 1241 `{"key":1`, 1242 `{"key":1,`, 1243 } 1244 1245 func TestUnmarshalSyntax(t *testing.T) { 1246 var x interface{} 1247 for _, src := range unmarshalSyntaxTests { 1248 err := Unmarshal([]byte(src), &x) 1249 if _, ok := err.(*SyntaxError); !ok { 1250 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) 1251 } 1252 } 1253 } 1254 1255 // Test handling of unexported fields that should be ignored. 1256 // Issue 4660 1257 type unexportedFields struct { 1258 Name string 1259 m map[string]interface{} `json:"-"` 1260 m2 map[string]interface{} `json:"abcd"` 1261 } 1262 1263 func TestUnmarshalUnexported(t *testing.T) { 1264 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}` 1265 want := &unexportedFields{Name: "Bob"} 1266 1267 out := &unexportedFields{} 1268 err := Unmarshal([]byte(input), out) 1269 if err != nil { 1270 t.Errorf("got error %v, expected nil", err) 1271 } 1272 if !reflect.DeepEqual(out, want) { 1273 t.Errorf("got %q, want %q", out, want) 1274 } 1275 } 1276 1277 // Time3339 is a time.Time which encodes to and from JSON 1278 // as an RFC 3339 time in UTC. 1279 type Time3339 time.Time 1280 1281 func (t *Time3339) UnmarshalJSON(b []byte) error { 1282 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { 1283 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) 1284 } 1285 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) 1286 if err != nil { 1287 return err 1288 } 1289 *t = Time3339(tm) 1290 return nil 1291 } 1292 1293 func TestUnmarshalJSONLiteralError(t *testing.T) { 1294 var t3 Time3339 1295 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) 1296 if err == nil { 1297 t.Fatalf("expected error; got time %v", time.Time(t3)) 1298 } 1299 if !strings.Contains(err.Error(), "range") { 1300 t.Errorf("got err = %v; want out of range error", err) 1301 } 1302 } 1303 1304 // Test that extra object elements in an array do not result in a 1305 // "data changing underfoot" error. 1306 // Issue 3717 1307 func TestSkipArrayObjects(t *testing.T) { 1308 json := `[{}]` 1309 var dest [0]interface{} 1310 1311 err := Unmarshal([]byte(json), &dest) 1312 if err != nil { 1313 t.Errorf("got error %q, want nil", err) 1314 } 1315 } 1316 1317 // Test semantics of pre-filled struct fields and pre-filled map fields. 1318 // Issue 4900. 1319 func TestPrefilled(t *testing.T) { 1320 ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m } 1321 1322 // Values here change, cannot reuse table across runs. 1323 var prefillTests = []struct { 1324 in string 1325 ptr interface{} 1326 out interface{} 1327 }{ 1328 { 1329 in: `{"X": 1, "Y": 2}`, 1330 ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5}, 1331 out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5}, 1332 }, 1333 { 1334 in: `{"X": 1, "Y": 2}`, 1335 ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}), 1336 out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}), 1337 }, 1338 } 1339 1340 for _, tt := range prefillTests { 1341 ptrstr := fmt.Sprintf("%v", tt.ptr) 1342 err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here 1343 if err != nil { 1344 t.Errorf("Unmarshal: %v", err) 1345 } 1346 if !reflect.DeepEqual(tt.ptr, tt.out) { 1347 t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out) 1348 } 1349 } 1350 } 1351 1352 var invalidUnmarshalTests = []struct { 1353 v interface{} 1354 want string 1355 }{ 1356 {nil, "json: Unmarshal(nil)"}, 1357 {struct{}{}, "json: Unmarshal(non-pointer struct {})"}, 1358 {(*int)(nil), "json: Unmarshal(nil *int)"}, 1359 } 1360 1361 func TestInvalidUnmarshal(t *testing.T) { 1362 buf := []byte(`{"a":"1"}`) 1363 for _, tt := range invalidUnmarshalTests { 1364 err := Unmarshal(buf, tt.v) 1365 if err == nil { 1366 t.Errorf("Unmarshal expecting error, got nil") 1367 continue 1368 } 1369 if got := err.Error(); got != tt.want { 1370 t.Errorf("Unmarshal = %q; want %q", got, tt.want) 1371 } 1372 } 1373 }