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