github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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 411 func TestMarshal(t *testing.T) { 412 b, err := Marshal(allValue) 413 if err != nil { 414 t.Fatalf("Marshal allValue: %v", err) 415 } 416 if string(b) != allValueCompact { 417 t.Errorf("Marshal allValueCompact") 418 diff(t, b, []byte(allValueCompact)) 419 return 420 } 421 422 b, err = Marshal(pallValue) 423 if err != nil { 424 t.Fatalf("Marshal pallValue: %v", err) 425 } 426 if string(b) != pallValueCompact { 427 t.Errorf("Marshal pallValueCompact") 428 diff(t, b, []byte(pallValueCompact)) 429 return 430 } 431 } 432 433 var badUTF8 = []struct { 434 in, out string 435 }{ 436 {"hello\xffworld", `"hello\ufffdworld"`}, 437 {"", `""`}, 438 {"\xff", `"\ufffd"`}, 439 {"\xff\xff", `"\ufffd\ufffd"`}, 440 {"a\xffb", `"a\ufffdb"`}, 441 {"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`}, 442 } 443 444 func TestMarshalBadUTF8(t *testing.T) { 445 for _, tt := range badUTF8 { 446 b, err := Marshal(tt.in) 447 if string(b) != tt.out || err != nil { 448 t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out) 449 } 450 } 451 } 452 453 func TestMarshalNumberZeroVal(t *testing.T) { 454 var n Number 455 out, err := Marshal(n) 456 if err != nil { 457 t.Fatal(err) 458 } 459 outStr := string(out) 460 if outStr != "0" { 461 t.Fatalf("Invalid zero val for Number: %q", outStr) 462 } 463 } 464 465 func TestMarshalEmbeds(t *testing.T) { 466 top := &Top{ 467 Level0: 1, 468 Embed0: Embed0{ 469 Level1b: 2, 470 Level1c: 3, 471 }, 472 Embed0a: &Embed0a{ 473 Level1a: 5, 474 Level1b: 6, 475 }, 476 Embed0b: &Embed0b{ 477 Level1a: 8, 478 Level1b: 9, 479 Level1c: 10, 480 Level1d: 11, 481 Level1e: 12, 482 }, 483 Loop: Loop{ 484 Loop1: 13, 485 Loop2: 14, 486 }, 487 Embed0p: Embed0p{ 488 Point: image.Point{X: 15, Y: 16}, 489 }, 490 Embed0q: Embed0q{ 491 Point: Point{Z: 17}, 492 }, 493 } 494 b, err := Marshal(top) 495 if err != nil { 496 t.Fatal(err) 497 } 498 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}" 499 if string(b) != want { 500 t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want) 501 } 502 } 503 504 func TestUnmarshal(t *testing.T) { 505 for i, tt := range unmarshalTests { 506 var scan scanner 507 in := []byte(tt.in) 508 if err := checkValid(in, &scan); err != nil { 509 if !reflect.DeepEqual(err, tt.err) { 510 t.Errorf("#%d: checkValid: %#v", i, err) 511 continue 512 } 513 } 514 if tt.ptr == nil { 515 continue 516 } 517 // v = new(right-type) 518 v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 519 dec := NewDecoder(bytes.NewReader(in)) 520 if tt.useNumber { 521 dec.UseNumber() 522 } 523 if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) { 524 t.Errorf("#%d: %v want %v", i, err, tt.err) 525 continue 526 } 527 if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { 528 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) 529 data, _ := Marshal(v.Elem().Interface()) 530 println(string(data)) 531 data, _ = Marshal(tt.out) 532 println(string(data)) 533 continue 534 } 535 536 // Check round trip. 537 if tt.err == nil { 538 enc, err := Marshal(v.Interface()) 539 if err != nil { 540 t.Errorf("#%d: error re-marshaling: %v", i, err) 541 continue 542 } 543 vv := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 544 dec = NewDecoder(bytes.NewReader(enc)) 545 if tt.useNumber { 546 dec.UseNumber() 547 } 548 if err := dec.Decode(vv.Interface()); err != nil { 549 t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err) 550 continue 551 } 552 if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) { 553 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface()) 554 t.Errorf(" In: %q", strings.Map(noSpace, string(in))) 555 t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc))) 556 continue 557 } 558 } 559 } 560 } 561 562 func TestUnmarshalMarshal(t *testing.T) { 563 initBig() 564 var v interface{} 565 if err := Unmarshal(jsonBig, &v); err != nil { 566 t.Fatalf("Unmarshal: %v", err) 567 } 568 b, err := Marshal(v) 569 if err != nil { 570 t.Fatalf("Marshal: %v", err) 571 } 572 if !bytes.Equal(jsonBig, b) { 573 t.Errorf("Marshal jsonBig") 574 diff(t, b, jsonBig) 575 return 576 } 577 } 578 579 var numberTests = []struct { 580 in string 581 i int64 582 intErr string 583 f float64 584 floatErr string 585 }{ 586 {in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1}, 587 {in: "-12", i: -12, f: -12.0}, 588 {in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"}, 589 } 590 591 // Independent of Decode, basic coverage of the accessors in Number 592 func TestNumberAccessors(t *testing.T) { 593 for _, tt := range numberTests { 594 n := Number(tt.in) 595 if s := n.String(); s != tt.in { 596 t.Errorf("Number(%q).String() is %q", tt.in, s) 597 } 598 if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i { 599 t.Errorf("Number(%q).Int64() is %d", tt.in, i) 600 } else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) { 601 t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err) 602 } 603 if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f { 604 t.Errorf("Number(%q).Float64() is %g", tt.in, f) 605 } else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) { 606 t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err) 607 } 608 } 609 } 610 611 func TestLargeByteSlice(t *testing.T) { 612 s0 := make([]byte, 2000) 613 for i := range s0 { 614 s0[i] = byte(i) 615 } 616 b, err := Marshal(s0) 617 if err != nil { 618 t.Fatalf("Marshal: %v", err) 619 } 620 var s1 []byte 621 if err := Unmarshal(b, &s1); err != nil { 622 t.Fatalf("Unmarshal: %v", err) 623 } 624 if !bytes.Equal(s0, s1) { 625 t.Errorf("Marshal large byte slice") 626 diff(t, s0, s1) 627 } 628 } 629 630 type Xint struct { 631 X int 632 } 633 634 func TestUnmarshalInterface(t *testing.T) { 635 var xint Xint 636 var i interface{} = &xint 637 if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil { 638 t.Fatalf("Unmarshal: %v", err) 639 } 640 if xint.X != 1 { 641 t.Fatalf("Did not write to xint") 642 } 643 } 644 645 func TestUnmarshalPtrPtr(t *testing.T) { 646 var xint Xint 647 pxint := &xint 648 if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil { 649 t.Fatalf("Unmarshal: %v", err) 650 } 651 if xint.X != 1 { 652 t.Fatalf("Did not write to xint") 653 } 654 } 655 656 func TestEscape(t *testing.T) { 657 const input = `"foobar"<html>` + " [\u2028 \u2029]" 658 const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"` 659 b, err := Marshal(input) 660 if err != nil { 661 t.Fatalf("Marshal error: %v", err) 662 } 663 if s := string(b); s != expected { 664 t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected) 665 } 666 } 667 668 // WrongString is a struct that's misusing the ,string modifier. 669 type WrongString struct { 670 Message string `json:"result,string"` 671 } 672 673 type wrongStringTest struct { 674 in, err string 675 } 676 677 var wrongStringTests = []wrongStringTest{ 678 {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`}, 679 {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`}, 680 {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`}, 681 } 682 683 // If people misuse the ,string modifier, the error message should be 684 // helpful, telling the user that they're doing it wrong. 685 func TestErrorMessageFromMisusedString(t *testing.T) { 686 for n, tt := range wrongStringTests { 687 r := strings.NewReader(tt.in) 688 var s WrongString 689 err := NewDecoder(r).Decode(&s) 690 got := fmt.Sprintf("%v", err) 691 if got != tt.err { 692 t.Errorf("%d. got err = %q, want %q", n, got, tt.err) 693 } 694 } 695 } 696 697 func noSpace(c rune) rune { 698 if isSpace(c) { 699 return -1 700 } 701 return c 702 } 703 704 type All struct { 705 Bool bool 706 Int int 707 Int8 int8 708 Int16 int16 709 Int32 int32 710 Int64 int64 711 Uint uint 712 Uint8 uint8 713 Uint16 uint16 714 Uint32 uint32 715 Uint64 uint64 716 Uintptr uintptr 717 Float32 float32 718 Float64 float64 719 720 Foo string `json:"bar"` 721 Foo2 string `json:"bar2,dummyopt"` 722 723 IntStr int64 `json:",string"` 724 725 PBool *bool 726 PInt *int 727 PInt8 *int8 728 PInt16 *int16 729 PInt32 *int32 730 PInt64 *int64 731 PUint *uint 732 PUint8 *uint8 733 PUint16 *uint16 734 PUint32 *uint32 735 PUint64 *uint64 736 PUintptr *uintptr 737 PFloat32 *float32 738 PFloat64 *float64 739 740 String string 741 PString *string 742 743 Map map[string]Small 744 MapP map[string]*Small 745 PMap *map[string]Small 746 PMapP *map[string]*Small 747 748 EmptyMap map[string]Small 749 NilMap map[string]Small 750 751 Slice []Small 752 SliceP []*Small 753 PSlice *[]Small 754 PSliceP *[]*Small 755 756 EmptySlice []Small 757 NilSlice []Small 758 759 StringSlice []string 760 ByteSlice []byte 761 762 Small Small 763 PSmall *Small 764 PPSmall **Small 765 766 Interface interface{} 767 PInterface *interface{} 768 769 unexported int 770 } 771 772 type Small struct { 773 Tag string 774 } 775 776 var allValue = All{ 777 Bool: true, 778 Int: 2, 779 Int8: 3, 780 Int16: 4, 781 Int32: 5, 782 Int64: 6, 783 Uint: 7, 784 Uint8: 8, 785 Uint16: 9, 786 Uint32: 10, 787 Uint64: 11, 788 Uintptr: 12, 789 Float32: 14.1, 790 Float64: 15.1, 791 Foo: "foo", 792 Foo2: "foo2", 793 IntStr: 42, 794 String: "16", 795 Map: map[string]Small{ 796 "17": {Tag: "tag17"}, 797 "18": {Tag: "tag18"}, 798 }, 799 MapP: map[string]*Small{ 800 "19": {Tag: "tag19"}, 801 "20": nil, 802 }, 803 EmptyMap: map[string]Small{}, 804 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, 805 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, 806 EmptySlice: []Small{}, 807 StringSlice: []string{"str24", "str25", "str26"}, 808 ByteSlice: []byte{27, 28, 29}, 809 Small: Small{Tag: "tag30"}, 810 PSmall: &Small{Tag: "tag31"}, 811 Interface: 5.2, 812 } 813 814 var pallValue = All{ 815 PBool: &allValue.Bool, 816 PInt: &allValue.Int, 817 PInt8: &allValue.Int8, 818 PInt16: &allValue.Int16, 819 PInt32: &allValue.Int32, 820 PInt64: &allValue.Int64, 821 PUint: &allValue.Uint, 822 PUint8: &allValue.Uint8, 823 PUint16: &allValue.Uint16, 824 PUint32: &allValue.Uint32, 825 PUint64: &allValue.Uint64, 826 PUintptr: &allValue.Uintptr, 827 PFloat32: &allValue.Float32, 828 PFloat64: &allValue.Float64, 829 PString: &allValue.String, 830 PMap: &allValue.Map, 831 PMapP: &allValue.MapP, 832 PSlice: &allValue.Slice, 833 PSliceP: &allValue.SliceP, 834 PPSmall: &allValue.PSmall, 835 PInterface: &allValue.Interface, 836 } 837 838 var allValueIndent = `{ 839 "Bool": true, 840 "Int": 2, 841 "Int8": 3, 842 "Int16": 4, 843 "Int32": 5, 844 "Int64": 6, 845 "Uint": 7, 846 "Uint8": 8, 847 "Uint16": 9, 848 "Uint32": 10, 849 "Uint64": 11, 850 "Uintptr": 12, 851 "Float32": 14.1, 852 "Float64": 15.1, 853 "bar": "foo", 854 "bar2": "foo2", 855 "IntStr": "42", 856 "PBool": null, 857 "PInt": null, 858 "PInt8": null, 859 "PInt16": null, 860 "PInt32": null, 861 "PInt64": null, 862 "PUint": null, 863 "PUint8": null, 864 "PUint16": null, 865 "PUint32": null, 866 "PUint64": null, 867 "PUintptr": null, 868 "PFloat32": null, 869 "PFloat64": null, 870 "String": "16", 871 "PString": null, 872 "Map": { 873 "17": { 874 "Tag": "tag17" 875 }, 876 "18": { 877 "Tag": "tag18" 878 } 879 }, 880 "MapP": { 881 "19": { 882 "Tag": "tag19" 883 }, 884 "20": null 885 }, 886 "PMap": null, 887 "PMapP": null, 888 "EmptyMap": {}, 889 "NilMap": null, 890 "Slice": [ 891 { 892 "Tag": "tag20" 893 }, 894 { 895 "Tag": "tag21" 896 } 897 ], 898 "SliceP": [ 899 { 900 "Tag": "tag22" 901 }, 902 null, 903 { 904 "Tag": "tag23" 905 } 906 ], 907 "PSlice": null, 908 "PSliceP": null, 909 "EmptySlice": [], 910 "NilSlice": null, 911 "StringSlice": [ 912 "str24", 913 "str25", 914 "str26" 915 ], 916 "ByteSlice": "Gxwd", 917 "Small": { 918 "Tag": "tag30" 919 }, 920 "PSmall": { 921 "Tag": "tag31" 922 }, 923 "PPSmall": null, 924 "Interface": 5.2, 925 "PInterface": null 926 }` 927 928 var allValueCompact = strings.Map(noSpace, allValueIndent) 929 930 var pallValueIndent = `{ 931 "Bool": false, 932 "Int": 0, 933 "Int8": 0, 934 "Int16": 0, 935 "Int32": 0, 936 "Int64": 0, 937 "Uint": 0, 938 "Uint8": 0, 939 "Uint16": 0, 940 "Uint32": 0, 941 "Uint64": 0, 942 "Uintptr": 0, 943 "Float32": 0, 944 "Float64": 0, 945 "bar": "", 946 "bar2": "", 947 "IntStr": "0", 948 "PBool": true, 949 "PInt": 2, 950 "PInt8": 3, 951 "PInt16": 4, 952 "PInt32": 5, 953 "PInt64": 6, 954 "PUint": 7, 955 "PUint8": 8, 956 "PUint16": 9, 957 "PUint32": 10, 958 "PUint64": 11, 959 "PUintptr": 12, 960 "PFloat32": 14.1, 961 "PFloat64": 15.1, 962 "String": "", 963 "PString": "16", 964 "Map": null, 965 "MapP": null, 966 "PMap": { 967 "17": { 968 "Tag": "tag17" 969 }, 970 "18": { 971 "Tag": "tag18" 972 } 973 }, 974 "PMapP": { 975 "19": { 976 "Tag": "tag19" 977 }, 978 "20": null 979 }, 980 "EmptyMap": null, 981 "NilMap": null, 982 "Slice": null, 983 "SliceP": null, 984 "PSlice": [ 985 { 986 "Tag": "tag20" 987 }, 988 { 989 "Tag": "tag21" 990 } 991 ], 992 "PSliceP": [ 993 { 994 "Tag": "tag22" 995 }, 996 null, 997 { 998 "Tag": "tag23" 999 } 1000 ], 1001 "EmptySlice": null, 1002 "NilSlice": null, 1003 "StringSlice": null, 1004 "ByteSlice": null, 1005 "Small": { 1006 "Tag": "" 1007 }, 1008 "PSmall": null, 1009 "PPSmall": { 1010 "Tag": "tag31" 1011 }, 1012 "Interface": null, 1013 "PInterface": 5.2 1014 }` 1015 1016 var pallValueCompact = strings.Map(noSpace, pallValueIndent) 1017 1018 func TestRefUnmarshal(t *testing.T) { 1019 type S struct { 1020 // Ref is defined in encode_test.go. 1021 R0 Ref 1022 R1 *Ref 1023 R2 RefText 1024 R3 *RefText 1025 } 1026 want := S{ 1027 R0: 12, 1028 R1: new(Ref), 1029 R2: 13, 1030 R3: new(RefText), 1031 } 1032 *want.R1 = 12 1033 *want.R3 = 13 1034 1035 var got S 1036 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil { 1037 t.Fatalf("Unmarshal: %v", err) 1038 } 1039 if !reflect.DeepEqual(got, want) { 1040 t.Errorf("got %+v, want %+v", got, want) 1041 } 1042 } 1043 1044 // Test that the empty string doesn't panic decoding when ,string is specified 1045 // Issue 3450 1046 func TestEmptyString(t *testing.T) { 1047 type T2 struct { 1048 Number1 int `json:",string"` 1049 Number2 int `json:",string"` 1050 } 1051 data := `{"Number1":"1", "Number2":""}` 1052 dec := NewDecoder(strings.NewReader(data)) 1053 var t2 T2 1054 err := dec.Decode(&t2) 1055 if err == nil { 1056 t.Fatal("Decode: did not return error") 1057 } 1058 if t2.Number1 != 1 { 1059 t.Fatal("Decode: did not set Number1") 1060 } 1061 } 1062 1063 func intp(x int) *int { 1064 p := new(int) 1065 *p = x 1066 return p 1067 } 1068 1069 func intpp(x *int) **int { 1070 pp := new(*int) 1071 *pp = x 1072 return pp 1073 } 1074 1075 var interfaceSetTests = []struct { 1076 pre interface{} 1077 json string 1078 post interface{} 1079 }{ 1080 {"foo", `"bar"`, "bar"}, 1081 {"foo", `2`, 2.0}, 1082 {"foo", `true`, true}, 1083 {"foo", `null`, nil}, 1084 1085 {nil, `null`, nil}, 1086 {new(int), `null`, nil}, 1087 {(*int)(nil), `null`, nil}, 1088 {new(*int), `null`, new(*int)}, 1089 {(**int)(nil), `null`, nil}, 1090 {intp(1), `null`, nil}, 1091 {intpp(nil), `null`, intpp(nil)}, 1092 {intpp(intp(1)), `null`, intpp(nil)}, 1093 } 1094 1095 func TestInterfaceSet(t *testing.T) { 1096 for _, tt := range interfaceSetTests { 1097 b := struct{ X interface{} }{tt.pre} 1098 blob := `{"X":` + tt.json + `}` 1099 if err := Unmarshal([]byte(blob), &b); err != nil { 1100 t.Errorf("Unmarshal %#q: %v", blob, err) 1101 continue 1102 } 1103 if !reflect.DeepEqual(b.X, tt.post) { 1104 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post) 1105 } 1106 } 1107 } 1108 1109 // JSON null values should be ignored for primitives and string values instead of resulting in an error. 1110 // Issue 2540 1111 func TestUnmarshalNulls(t *testing.T) { 1112 jsonData := []byte(`{ 1113 "Bool" : null, 1114 "Int" : null, 1115 "Int8" : null, 1116 "Int16" : null, 1117 "Int32" : null, 1118 "Int64" : null, 1119 "Uint" : null, 1120 "Uint8" : null, 1121 "Uint16" : null, 1122 "Uint32" : null, 1123 "Uint64" : null, 1124 "Float32" : null, 1125 "Float64" : null, 1126 "String" : null}`) 1127 1128 nulls := All{ 1129 Bool: true, 1130 Int: 2, 1131 Int8: 3, 1132 Int16: 4, 1133 Int32: 5, 1134 Int64: 6, 1135 Uint: 7, 1136 Uint8: 8, 1137 Uint16: 9, 1138 Uint32: 10, 1139 Uint64: 11, 1140 Float32: 12.1, 1141 Float64: 13.1, 1142 String: "14"} 1143 1144 err := Unmarshal(jsonData, &nulls) 1145 if err != nil { 1146 t.Errorf("Unmarshal of null values failed: %v", err) 1147 } 1148 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 || 1149 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 || 1150 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" { 1151 1152 t.Errorf("Unmarshal of null values affected primitives") 1153 } 1154 } 1155 1156 func TestStringKind(t *testing.T) { 1157 type stringKind string 1158 1159 var m1, m2 map[stringKind]int 1160 m1 = map[stringKind]int{ 1161 "foo": 42, 1162 } 1163 1164 data, err := Marshal(m1) 1165 if err != nil { 1166 t.Errorf("Unexpected error marshalling: %v", err) 1167 } 1168 1169 err = Unmarshal(data, &m2) 1170 if err != nil { 1171 t.Errorf("Unexpected error unmarshalling: %v", err) 1172 } 1173 1174 if !reflect.DeepEqual(m1, m2) { 1175 t.Error("Items should be equal after encoding and then decoding") 1176 } 1177 1178 } 1179 1180 var decodeTypeErrorTests = []struct { 1181 dest interface{} 1182 src string 1183 }{ 1184 {new(string), `{"user": "name"}`}, // issue 4628. 1185 {new(error), `{}`}, // issue 4222 1186 {new(error), `[]`}, 1187 {new(error), `""`}, 1188 {new(error), `123`}, 1189 {new(error), `true`}, 1190 } 1191 1192 func TestUnmarshalTypeError(t *testing.T) { 1193 for _, item := range decodeTypeErrorTests { 1194 err := Unmarshal([]byte(item.src), item.dest) 1195 if _, ok := err.(*UnmarshalTypeError); !ok { 1196 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", 1197 item.src, item.dest, err) 1198 } 1199 } 1200 } 1201 1202 var unmarshalSyntaxTests = []string{ 1203 "tru", 1204 "fals", 1205 "nul", 1206 "123e", 1207 `"hello`, 1208 `[1,2,3`, 1209 `{"key":1`, 1210 `{"key":1,`, 1211 } 1212 1213 func TestUnmarshalSyntax(t *testing.T) { 1214 var x interface{} 1215 for _, src := range unmarshalSyntaxTests { 1216 err := Unmarshal([]byte(src), &x) 1217 if _, ok := err.(*SyntaxError); !ok { 1218 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) 1219 } 1220 } 1221 } 1222 1223 // Test handling of unexported fields that should be ignored. 1224 // Issue 4660 1225 type unexportedFields struct { 1226 Name string 1227 m map[string]interface{} `json:"-"` 1228 m2 map[string]interface{} `json:"abcd"` 1229 } 1230 1231 func TestUnmarshalUnexported(t *testing.T) { 1232 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}` 1233 want := &unexportedFields{Name: "Bob"} 1234 1235 out := &unexportedFields{} 1236 err := Unmarshal([]byte(input), out) 1237 if err != nil { 1238 t.Errorf("got error %v, expected nil", err) 1239 } 1240 if !reflect.DeepEqual(out, want) { 1241 t.Errorf("got %q, want %q", out, want) 1242 } 1243 } 1244 1245 // Time3339 is a time.Time which encodes to and from JSON 1246 // as an RFC 3339 time in UTC. 1247 type Time3339 time.Time 1248 1249 func (t *Time3339) UnmarshalJSON(b []byte) error { 1250 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { 1251 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) 1252 } 1253 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) 1254 if err != nil { 1255 return err 1256 } 1257 *t = Time3339(tm) 1258 return nil 1259 } 1260 1261 func TestUnmarshalJSONLiteralError(t *testing.T) { 1262 var t3 Time3339 1263 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) 1264 if err == nil { 1265 t.Fatalf("expected error; got time %v", time.Time(t3)) 1266 } 1267 if !strings.Contains(err.Error(), "range") { 1268 t.Errorf("got err = %v; want out of range error", err) 1269 } 1270 } 1271 1272 // Test that extra object elements in an array do not result in a 1273 // "data changing underfoot" error. 1274 // Issue 3717 1275 func TestSkipArrayObjects(t *testing.T) { 1276 json := `[{}]` 1277 var dest [0]interface{} 1278 1279 err := Unmarshal([]byte(json), &dest) 1280 if err != nil { 1281 t.Errorf("got error %q, want nil", err) 1282 } 1283 } 1284 1285 // Test semantics of pre-filled struct fields and pre-filled map fields. 1286 // Issue 4900. 1287 func TestPrefilled(t *testing.T) { 1288 ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m } 1289 1290 // Values here change, cannot reuse table across runs. 1291 var prefillTests = []struct { 1292 in string 1293 ptr interface{} 1294 out interface{} 1295 }{ 1296 { 1297 in: `{"X": 1, "Y": 2}`, 1298 ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5}, 1299 out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5}, 1300 }, 1301 { 1302 in: `{"X": 1, "Y": 2}`, 1303 ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}), 1304 out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}), 1305 }, 1306 } 1307 1308 for _, tt := range prefillTests { 1309 ptrstr := fmt.Sprintf("%v", tt.ptr) 1310 err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here 1311 if err != nil { 1312 t.Errorf("Unmarshal: %v", err) 1313 } 1314 if !reflect.DeepEqual(tt.ptr, tt.out) { 1315 t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out) 1316 } 1317 } 1318 }