github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/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 {`{"result":123}`, `json: invalid use of ,string struct tag, trying to unmarshal unquoted value into string`}, 692 } 693 694 // If people misuse the ,string modifier, the error message should be 695 // helpful, telling the user that they're doing it wrong. 696 func TestErrorMessageFromMisusedString(t *testing.T) { 697 for n, tt := range wrongStringTests { 698 r := strings.NewReader(tt.in) 699 var s WrongString 700 err := NewDecoder(r).Decode(&s) 701 got := fmt.Sprintf("%v", err) 702 if got != tt.err { 703 t.Errorf("%d. got err = %q, want %q", n, got, tt.err) 704 } 705 } 706 } 707 708 func noSpace(c rune) rune { 709 if isSpace(c) { 710 return -1 711 } 712 return c 713 } 714 715 type All struct { 716 Bool bool 717 Int int 718 Int8 int8 719 Int16 int16 720 Int32 int32 721 Int64 int64 722 Uint uint 723 Uint8 uint8 724 Uint16 uint16 725 Uint32 uint32 726 Uint64 uint64 727 Uintptr uintptr 728 Float32 float32 729 Float64 float64 730 731 Foo string `json:"bar"` 732 Foo2 string `json:"bar2,dummyopt"` 733 734 IntStr int64 `json:",string"` 735 736 PBool *bool 737 PInt *int 738 PInt8 *int8 739 PInt16 *int16 740 PInt32 *int32 741 PInt64 *int64 742 PUint *uint 743 PUint8 *uint8 744 PUint16 *uint16 745 PUint32 *uint32 746 PUint64 *uint64 747 PUintptr *uintptr 748 PFloat32 *float32 749 PFloat64 *float64 750 751 String string 752 PString *string 753 754 Map map[string]Small 755 MapP map[string]*Small 756 PMap *map[string]Small 757 PMapP *map[string]*Small 758 759 EmptyMap map[string]Small 760 NilMap map[string]Small 761 762 Slice []Small 763 SliceP []*Small 764 PSlice *[]Small 765 PSliceP *[]*Small 766 767 EmptySlice []Small 768 NilSlice []Small 769 770 StringSlice []string 771 ByteSlice []byte 772 773 Small Small 774 PSmall *Small 775 PPSmall **Small 776 777 Interface interface{} 778 PInterface *interface{} 779 780 unexported int 781 } 782 783 type Small struct { 784 Tag string 785 } 786 787 var allValue = All{ 788 Bool: true, 789 Int: 2, 790 Int8: 3, 791 Int16: 4, 792 Int32: 5, 793 Int64: 6, 794 Uint: 7, 795 Uint8: 8, 796 Uint16: 9, 797 Uint32: 10, 798 Uint64: 11, 799 Uintptr: 12, 800 Float32: 14.1, 801 Float64: 15.1, 802 Foo: "foo", 803 Foo2: "foo2", 804 IntStr: 42, 805 String: "16", 806 Map: map[string]Small{ 807 "17": {Tag: "tag17"}, 808 "18": {Tag: "tag18"}, 809 }, 810 MapP: map[string]*Small{ 811 "19": {Tag: "tag19"}, 812 "20": nil, 813 }, 814 EmptyMap: map[string]Small{}, 815 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, 816 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, 817 EmptySlice: []Small{}, 818 StringSlice: []string{"str24", "str25", "str26"}, 819 ByteSlice: []byte{27, 28, 29}, 820 Small: Small{Tag: "tag30"}, 821 PSmall: &Small{Tag: "tag31"}, 822 Interface: 5.2, 823 } 824 825 var pallValue = All{ 826 PBool: &allValue.Bool, 827 PInt: &allValue.Int, 828 PInt8: &allValue.Int8, 829 PInt16: &allValue.Int16, 830 PInt32: &allValue.Int32, 831 PInt64: &allValue.Int64, 832 PUint: &allValue.Uint, 833 PUint8: &allValue.Uint8, 834 PUint16: &allValue.Uint16, 835 PUint32: &allValue.Uint32, 836 PUint64: &allValue.Uint64, 837 PUintptr: &allValue.Uintptr, 838 PFloat32: &allValue.Float32, 839 PFloat64: &allValue.Float64, 840 PString: &allValue.String, 841 PMap: &allValue.Map, 842 PMapP: &allValue.MapP, 843 PSlice: &allValue.Slice, 844 PSliceP: &allValue.SliceP, 845 PPSmall: &allValue.PSmall, 846 PInterface: &allValue.Interface, 847 } 848 849 var allValueIndent = `{ 850 "Bool": true, 851 "Int": 2, 852 "Int8": 3, 853 "Int16": 4, 854 "Int32": 5, 855 "Int64": 6, 856 "Uint": 7, 857 "Uint8": 8, 858 "Uint16": 9, 859 "Uint32": 10, 860 "Uint64": 11, 861 "Uintptr": 12, 862 "Float32": 14.1, 863 "Float64": 15.1, 864 "bar": "foo", 865 "bar2": "foo2", 866 "IntStr": "42", 867 "PBool": null, 868 "PInt": null, 869 "PInt8": null, 870 "PInt16": null, 871 "PInt32": null, 872 "PInt64": null, 873 "PUint": null, 874 "PUint8": null, 875 "PUint16": null, 876 "PUint32": null, 877 "PUint64": null, 878 "PUintptr": null, 879 "PFloat32": null, 880 "PFloat64": null, 881 "String": "16", 882 "PString": null, 883 "Map": { 884 "17": { 885 "Tag": "tag17" 886 }, 887 "18": { 888 "Tag": "tag18" 889 } 890 }, 891 "MapP": { 892 "19": { 893 "Tag": "tag19" 894 }, 895 "20": null 896 }, 897 "PMap": null, 898 "PMapP": null, 899 "EmptyMap": {}, 900 "NilMap": null, 901 "Slice": [ 902 { 903 "Tag": "tag20" 904 }, 905 { 906 "Tag": "tag21" 907 } 908 ], 909 "SliceP": [ 910 { 911 "Tag": "tag22" 912 }, 913 null, 914 { 915 "Tag": "tag23" 916 } 917 ], 918 "PSlice": null, 919 "PSliceP": null, 920 "EmptySlice": [], 921 "NilSlice": null, 922 "StringSlice": [ 923 "str24", 924 "str25", 925 "str26" 926 ], 927 "ByteSlice": "Gxwd", 928 "Small": { 929 "Tag": "tag30" 930 }, 931 "PSmall": { 932 "Tag": "tag31" 933 }, 934 "PPSmall": null, 935 "Interface": 5.2, 936 "PInterface": null 937 }` 938 939 var allValueCompact = strings.Map(noSpace, allValueIndent) 940 941 var pallValueIndent = `{ 942 "Bool": false, 943 "Int": 0, 944 "Int8": 0, 945 "Int16": 0, 946 "Int32": 0, 947 "Int64": 0, 948 "Uint": 0, 949 "Uint8": 0, 950 "Uint16": 0, 951 "Uint32": 0, 952 "Uint64": 0, 953 "Uintptr": 0, 954 "Float32": 0, 955 "Float64": 0, 956 "bar": "", 957 "bar2": "", 958 "IntStr": "0", 959 "PBool": true, 960 "PInt": 2, 961 "PInt8": 3, 962 "PInt16": 4, 963 "PInt32": 5, 964 "PInt64": 6, 965 "PUint": 7, 966 "PUint8": 8, 967 "PUint16": 9, 968 "PUint32": 10, 969 "PUint64": 11, 970 "PUintptr": 12, 971 "PFloat32": 14.1, 972 "PFloat64": 15.1, 973 "String": "", 974 "PString": "16", 975 "Map": null, 976 "MapP": null, 977 "PMap": { 978 "17": { 979 "Tag": "tag17" 980 }, 981 "18": { 982 "Tag": "tag18" 983 } 984 }, 985 "PMapP": { 986 "19": { 987 "Tag": "tag19" 988 }, 989 "20": null 990 }, 991 "EmptyMap": null, 992 "NilMap": null, 993 "Slice": null, 994 "SliceP": null, 995 "PSlice": [ 996 { 997 "Tag": "tag20" 998 }, 999 { 1000 "Tag": "tag21" 1001 } 1002 ], 1003 "PSliceP": [ 1004 { 1005 "Tag": "tag22" 1006 }, 1007 null, 1008 { 1009 "Tag": "tag23" 1010 } 1011 ], 1012 "EmptySlice": null, 1013 "NilSlice": null, 1014 "StringSlice": null, 1015 "ByteSlice": null, 1016 "Small": { 1017 "Tag": "" 1018 }, 1019 "PSmall": null, 1020 "PPSmall": { 1021 "Tag": "tag31" 1022 }, 1023 "Interface": null, 1024 "PInterface": 5.2 1025 }` 1026 1027 var pallValueCompact = strings.Map(noSpace, pallValueIndent) 1028 1029 func TestRefUnmarshal(t *testing.T) { 1030 type S struct { 1031 // Ref is defined in encode_test.go. 1032 R0 Ref 1033 R1 *Ref 1034 R2 RefText 1035 R3 *RefText 1036 } 1037 want := S{ 1038 R0: 12, 1039 R1: new(Ref), 1040 R2: 13, 1041 R3: new(RefText), 1042 } 1043 *want.R1 = 12 1044 *want.R3 = 13 1045 1046 var got S 1047 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil { 1048 t.Fatalf("Unmarshal: %v", err) 1049 } 1050 if !reflect.DeepEqual(got, want) { 1051 t.Errorf("got %+v, want %+v", got, want) 1052 } 1053 } 1054 1055 // Test that the empty string doesn't panic decoding when ,string is specified 1056 // Issue 3450 1057 func TestEmptyString(t *testing.T) { 1058 type T2 struct { 1059 Number1 int `json:",string"` 1060 Number2 int `json:",string"` 1061 } 1062 data := `{"Number1":"1", "Number2":""}` 1063 dec := NewDecoder(strings.NewReader(data)) 1064 var t2 T2 1065 err := dec.Decode(&t2) 1066 if err == nil { 1067 t.Fatal("Decode: did not return error") 1068 } 1069 if t2.Number1 != 1 { 1070 t.Fatal("Decode: did not set Number1") 1071 } 1072 } 1073 1074 // Test that a null for ,string is not replaced with the previous quoted string (issue 7046). 1075 // It should also not be an error (issue 2540, issue 8587). 1076 func TestNullString(t *testing.T) { 1077 type T struct { 1078 A int `json:",string"` 1079 B int `json:",string"` 1080 C *int `json:",string"` 1081 } 1082 data := []byte(`{"A": "1", "B": null, "C": null}`) 1083 var s T 1084 s.B = 1 1085 s.C = new(int) 1086 *s.C = 2 1087 err := Unmarshal(data, &s) 1088 if err != nil { 1089 t.Fatalf("Unmarshal: %v", err) 1090 } 1091 if s.B != 1 || s.C != nil { 1092 t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C) 1093 } 1094 } 1095 1096 func intp(x int) *int { 1097 p := new(int) 1098 *p = x 1099 return p 1100 } 1101 1102 func intpp(x *int) **int { 1103 pp := new(*int) 1104 *pp = x 1105 return pp 1106 } 1107 1108 var interfaceSetTests = []struct { 1109 pre interface{} 1110 json string 1111 post interface{} 1112 }{ 1113 {"foo", `"bar"`, "bar"}, 1114 {"foo", `2`, 2.0}, 1115 {"foo", `true`, true}, 1116 {"foo", `null`, nil}, 1117 1118 {nil, `null`, nil}, 1119 {new(int), `null`, nil}, 1120 {(*int)(nil), `null`, nil}, 1121 {new(*int), `null`, new(*int)}, 1122 {(**int)(nil), `null`, nil}, 1123 {intp(1), `null`, nil}, 1124 {intpp(nil), `null`, intpp(nil)}, 1125 {intpp(intp(1)), `null`, intpp(nil)}, 1126 } 1127 1128 func TestInterfaceSet(t *testing.T) { 1129 for _, tt := range interfaceSetTests { 1130 b := struct{ X interface{} }{tt.pre} 1131 blob := `{"X":` + tt.json + `}` 1132 if err := Unmarshal([]byte(blob), &b); err != nil { 1133 t.Errorf("Unmarshal %#q: %v", blob, err) 1134 continue 1135 } 1136 if !reflect.DeepEqual(b.X, tt.post) { 1137 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post) 1138 } 1139 } 1140 } 1141 1142 // JSON null values should be ignored for primitives and string values instead of resulting in an error. 1143 // Issue 2540 1144 func TestUnmarshalNulls(t *testing.T) { 1145 jsonData := []byte(`{ 1146 "Bool" : null, 1147 "Int" : null, 1148 "Int8" : null, 1149 "Int16" : null, 1150 "Int32" : null, 1151 "Int64" : null, 1152 "Uint" : null, 1153 "Uint8" : null, 1154 "Uint16" : null, 1155 "Uint32" : null, 1156 "Uint64" : null, 1157 "Float32" : null, 1158 "Float64" : null, 1159 "String" : null}`) 1160 1161 nulls := All{ 1162 Bool: true, 1163 Int: 2, 1164 Int8: 3, 1165 Int16: 4, 1166 Int32: 5, 1167 Int64: 6, 1168 Uint: 7, 1169 Uint8: 8, 1170 Uint16: 9, 1171 Uint32: 10, 1172 Uint64: 11, 1173 Float32: 12.1, 1174 Float64: 13.1, 1175 String: "14"} 1176 1177 err := Unmarshal(jsonData, &nulls) 1178 if err != nil { 1179 t.Errorf("Unmarshal of null values failed: %v", err) 1180 } 1181 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 || 1182 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 || 1183 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" { 1184 1185 t.Errorf("Unmarshal of null values affected primitives") 1186 } 1187 } 1188 1189 func TestStringKind(t *testing.T) { 1190 type stringKind string 1191 1192 var m1, m2 map[stringKind]int 1193 m1 = map[stringKind]int{ 1194 "foo": 42, 1195 } 1196 1197 data, err := Marshal(m1) 1198 if err != nil { 1199 t.Errorf("Unexpected error marshalling: %v", err) 1200 } 1201 1202 err = Unmarshal(data, &m2) 1203 if err != nil { 1204 t.Errorf("Unexpected error unmarshalling: %v", err) 1205 } 1206 1207 if !reflect.DeepEqual(m1, m2) { 1208 t.Error("Items should be equal after encoding and then decoding") 1209 } 1210 1211 } 1212 1213 var decodeTypeErrorTests = []struct { 1214 dest interface{} 1215 src string 1216 }{ 1217 {new(string), `{"user": "name"}`}, // issue 4628. 1218 {new(error), `{}`}, // issue 4222 1219 {new(error), `[]`}, 1220 {new(error), `""`}, 1221 {new(error), `123`}, 1222 {new(error), `true`}, 1223 } 1224 1225 func TestUnmarshalTypeError(t *testing.T) { 1226 for _, item := range decodeTypeErrorTests { 1227 err := Unmarshal([]byte(item.src), item.dest) 1228 if _, ok := err.(*UnmarshalTypeError); !ok { 1229 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", 1230 item.src, item.dest, err) 1231 } 1232 } 1233 } 1234 1235 var unmarshalSyntaxTests = []string{ 1236 "tru", 1237 "fals", 1238 "nul", 1239 "123e", 1240 `"hello`, 1241 `[1,2,3`, 1242 `{"key":1`, 1243 `{"key":1,`, 1244 } 1245 1246 func TestUnmarshalSyntax(t *testing.T) { 1247 var x interface{} 1248 for _, src := range unmarshalSyntaxTests { 1249 err := Unmarshal([]byte(src), &x) 1250 if _, ok := err.(*SyntaxError); !ok { 1251 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) 1252 } 1253 } 1254 } 1255 1256 // Test handling of unexported fields that should be ignored. 1257 // Issue 4660 1258 type unexportedFields struct { 1259 Name string 1260 m map[string]interface{} `json:"-"` 1261 m2 map[string]interface{} `json:"abcd"` 1262 } 1263 1264 func TestUnmarshalUnexported(t *testing.T) { 1265 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}` 1266 want := &unexportedFields{Name: "Bob"} 1267 1268 out := &unexportedFields{} 1269 err := Unmarshal([]byte(input), out) 1270 if err != nil { 1271 t.Errorf("got error %v, expected nil", err) 1272 } 1273 if !reflect.DeepEqual(out, want) { 1274 t.Errorf("got %q, want %q", out, want) 1275 } 1276 } 1277 1278 // Time3339 is a time.Time which encodes to and from JSON 1279 // as an RFC 3339 time in UTC. 1280 type Time3339 time.Time 1281 1282 func (t *Time3339) UnmarshalJSON(b []byte) error { 1283 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { 1284 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) 1285 } 1286 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) 1287 if err != nil { 1288 return err 1289 } 1290 *t = Time3339(tm) 1291 return nil 1292 } 1293 1294 func TestUnmarshalJSONLiteralError(t *testing.T) { 1295 var t3 Time3339 1296 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) 1297 if err == nil { 1298 t.Fatalf("expected error; got time %v", time.Time(t3)) 1299 } 1300 if !strings.Contains(err.Error(), "range") { 1301 t.Errorf("got err = %v; want out of range error", err) 1302 } 1303 } 1304 1305 // Test that extra object elements in an array do not result in a 1306 // "data changing underfoot" error. 1307 // Issue 3717 1308 func TestSkipArrayObjects(t *testing.T) { 1309 json := `[{}]` 1310 var dest [0]interface{} 1311 1312 err := Unmarshal([]byte(json), &dest) 1313 if err != nil { 1314 t.Errorf("got error %q, want nil", err) 1315 } 1316 } 1317 1318 // Test semantics of pre-filled struct fields and pre-filled map fields. 1319 // Issue 4900. 1320 func TestPrefilled(t *testing.T) { 1321 ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m } 1322 1323 // Values here change, cannot reuse table across runs. 1324 var prefillTests = []struct { 1325 in string 1326 ptr interface{} 1327 out interface{} 1328 }{ 1329 { 1330 in: `{"X": 1, "Y": 2}`, 1331 ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5}, 1332 out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5}, 1333 }, 1334 { 1335 in: `{"X": 1, "Y": 2}`, 1336 ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}), 1337 out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}), 1338 }, 1339 } 1340 1341 for _, tt := range prefillTests { 1342 ptrstr := fmt.Sprintf("%v", tt.ptr) 1343 err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here 1344 if err != nil { 1345 t.Errorf("Unmarshal: %v", err) 1346 } 1347 if !reflect.DeepEqual(tt.ptr, tt.out) { 1348 t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out) 1349 } 1350 } 1351 } 1352 1353 var invalidUnmarshalTests = []struct { 1354 v interface{} 1355 want string 1356 }{ 1357 {nil, "json: Unmarshal(nil)"}, 1358 {struct{}{}, "json: Unmarshal(non-pointer struct {})"}, 1359 {(*int)(nil), "json: Unmarshal(nil *int)"}, 1360 } 1361 1362 func TestInvalidUnmarshal(t *testing.T) { 1363 buf := []byte(`{"a":"1"}`) 1364 for _, tt := range invalidUnmarshalTests { 1365 err := Unmarshal(buf, tt.v) 1366 if err == nil { 1367 t.Errorf("Unmarshal expecting error, got nil") 1368 continue 1369 } 1370 if got := err.Error(); got != tt.want { 1371 t.Errorf("Unmarshal = %q; want %q", got, tt.want) 1372 } 1373 } 1374 }