github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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 "errors" 11 "fmt" 12 "image" 13 "math" 14 "net" 15 "reflect" 16 "strconv" 17 "strings" 18 "testing" 19 "time" 20 ) 21 22 type T struct { 23 X string 24 Y int 25 Z int `json:"-"` 26 } 27 28 type U struct { 29 Alphabet string `json:"alpha"` 30 } 31 32 type V struct { 33 F1 interface{} 34 F2 int32 35 F3 Number 36 } 37 38 // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and 39 // without UseNumber 40 var ifaceNumAsFloat64 = map[string]interface{}{ 41 "k1": float64(1), 42 "k2": "s", 43 "k3": []interface{}{float64(1), float64(2.0), float64(3e-3)}, 44 "k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)}, 45 } 46 47 var ifaceNumAsNumber = map[string]interface{}{ 48 "k1": Number("1"), 49 "k2": "s", 50 "k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")}, 51 "k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")}, 52 } 53 54 type tx struct { 55 x int 56 } 57 58 type u8 uint8 59 60 // A type that can unmarshal itself. 61 62 type unmarshaler struct { 63 T bool 64 } 65 66 func (u *unmarshaler) UnmarshalJSON(b []byte) error { 67 *u = unmarshaler{true} // All we need to see that UnmarshalJSON is called. 68 return nil 69 } 70 71 type ustruct struct { 72 M unmarshaler 73 } 74 75 type unmarshalerText struct { 76 A, B string 77 } 78 79 // needed for re-marshaling tests 80 func (u unmarshalerText) MarshalText() ([]byte, error) { 81 return []byte(u.A + ":" + u.B), nil 82 } 83 84 func (u *unmarshalerText) UnmarshalText(b []byte) error { 85 pos := bytes.Index(b, []byte(":")) 86 if pos == -1 { 87 return errors.New("missing separator") 88 } 89 u.A, u.B = string(b[:pos]), string(b[pos+1:]) 90 return nil 91 } 92 93 var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil) 94 95 type ustructText struct { 96 M unmarshalerText 97 } 98 99 // u8marshal is an integer type that can marshal/unmarshal itself. 100 type u8marshal uint8 101 102 func (u8 u8marshal) MarshalText() ([]byte, error) { 103 return []byte(fmt.Sprintf("u%d", u8)), nil 104 } 105 106 var errMissingU8Prefix = errors.New("missing 'u' prefix") 107 108 func (u8 *u8marshal) UnmarshalText(b []byte) error { 109 if !bytes.HasPrefix(b, []byte{'u'}) { 110 return errMissingU8Prefix 111 } 112 n, err := strconv.Atoi(string(b[1:])) 113 if err != nil { 114 return err 115 } 116 *u8 = u8marshal(n) 117 return nil 118 } 119 120 var _ encoding.TextUnmarshaler = (*u8marshal)(nil) 121 122 var ( 123 um0, um1 unmarshaler // target2 of unmarshaling 124 ump = &um1 125 umtrue = unmarshaler{true} 126 umslice = []unmarshaler{{true}} 127 umslicep = new([]unmarshaler) 128 umstruct = ustruct{unmarshaler{true}} 129 130 um0T, um1T unmarshalerText // target2 of unmarshaling 131 umpType = &um1T 132 umtrueXY = unmarshalerText{"x", "y"} 133 umsliceXY = []unmarshalerText{{"x", "y"}} 134 umslicepType = new([]unmarshalerText) 135 umstructType = new(ustructText) 136 umstructXY = ustructText{unmarshalerText{"x", "y"}} 137 138 ummapType = map[unmarshalerText]bool{} 139 ummapXY = map[unmarshalerText]bool{unmarshalerText{"x", "y"}: true} 140 ) 141 142 // Test data structures for anonymous fields. 143 144 type Point struct { 145 Z int 146 } 147 148 type Top struct { 149 Level0 int 150 Embed0 151 *Embed0a 152 *Embed0b `json:"e,omitempty"` // treated as named 153 Embed0c `json:"-"` // ignored 154 Loop 155 Embed0p // has Point with X, Y, used 156 Embed0q // has Point with Z, used 157 embed // contains exported field 158 } 159 160 type Embed0 struct { 161 Level1a int // overridden by Embed0a's Level1a with json tag 162 Level1b int // used because Embed0a's Level1b is renamed 163 Level1c int // used because Embed0a's Level1c is ignored 164 Level1d int // annihilated by Embed0a's Level1d 165 Level1e int `json:"x"` // annihilated by Embed0a.Level1e 166 } 167 168 type Embed0a struct { 169 Level1a int `json:"Level1a,omitempty"` 170 Level1b int `json:"LEVEL1B,omitempty"` 171 Level1c int `json:"-"` 172 Level1d int // annihilated by Embed0's Level1d 173 Level1f int `json:"x"` // annihilated by Embed0's Level1e 174 } 175 176 type Embed0b Embed0 177 178 type Embed0c Embed0 179 180 type Embed0p struct { 181 image.Point 182 } 183 184 type Embed0q struct { 185 Point 186 } 187 188 type embed struct { 189 Q int 190 } 191 192 type Loop struct { 193 Loop1 int `json:",omitempty"` 194 Loop2 int `json:",omitempty"` 195 *Loop 196 } 197 198 // From reflect test: 199 // The X in S6 and S7 annihilate, but they also block the X in S8.S9. 200 type S5 struct { 201 S6 202 S7 203 S8 204 } 205 206 type S6 struct { 207 X int 208 } 209 210 type S7 S6 211 212 type S8 struct { 213 S9 214 } 215 216 type S9 struct { 217 X int 218 Y int 219 } 220 221 // From reflect test: 222 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9. 223 type S10 struct { 224 S11 225 S12 226 S13 227 } 228 229 type S11 struct { 230 S6 231 } 232 233 type S12 struct { 234 S6 235 } 236 237 type S13 struct { 238 S8 239 } 240 241 type Ambig struct { 242 // Given "hello", the first match should win. 243 First int `json:"HELLO"` 244 Second int `json:"Hello"` 245 } 246 247 type XYZ struct { 248 X interface{} 249 Y interface{} 250 Z interface{} 251 } 252 253 func sliceAddr(x []int) *[]int { return &x } 254 func mapAddr(x map[string]int) *map[string]int { return &x } 255 256 type byteWithMarshalJSON byte 257 258 func (b byteWithMarshalJSON) MarshalJSON() ([]byte, error) { 259 return []byte(fmt.Sprintf(`"Z%.2x"`, byte(b))), nil 260 } 261 262 func (b *byteWithMarshalJSON) UnmarshalJSON(data []byte) error { 263 if len(data) != 5 || data[0] != '"' || data[1] != 'Z' || data[4] != '"' { 264 return fmt.Errorf("bad quoted string") 265 } 266 i, err := strconv.ParseInt(string(data[2:4]), 16, 8) 267 if err != nil { 268 return fmt.Errorf("bad hex") 269 } 270 *b = byteWithMarshalJSON(i) 271 return nil 272 } 273 274 type byteWithPtrMarshalJSON byte 275 276 func (b *byteWithPtrMarshalJSON) MarshalJSON() ([]byte, error) { 277 return byteWithMarshalJSON(*b).MarshalJSON() 278 } 279 280 func (b *byteWithPtrMarshalJSON) UnmarshalJSON(data []byte) error { 281 return (*byteWithMarshalJSON)(b).UnmarshalJSON(data) 282 } 283 284 type byteWithMarshalText byte 285 286 func (b byteWithMarshalText) MarshalText() ([]byte, error) { 287 return []byte(fmt.Sprintf(`Z%.2x`, byte(b))), nil 288 } 289 290 func (b *byteWithMarshalText) UnmarshalText(data []byte) error { 291 if len(data) != 3 || data[0] != 'Z' { 292 return fmt.Errorf("bad quoted string") 293 } 294 i, err := strconv.ParseInt(string(data[1:3]), 16, 8) 295 if err != nil { 296 return fmt.Errorf("bad hex") 297 } 298 *b = byteWithMarshalText(i) 299 return nil 300 } 301 302 type byteWithPtrMarshalText byte 303 304 func (b *byteWithPtrMarshalText) MarshalText() ([]byte, error) { 305 return byteWithMarshalText(*b).MarshalText() 306 } 307 308 func (b *byteWithPtrMarshalText) UnmarshalText(data []byte) error { 309 return (*byteWithMarshalText)(b).UnmarshalText(data) 310 } 311 312 type intWithMarshalJSON int 313 314 func (b intWithMarshalJSON) MarshalJSON() ([]byte, error) { 315 return []byte(fmt.Sprintf(`"Z%.2x"`, int(b))), nil 316 } 317 318 func (b *intWithMarshalJSON) UnmarshalJSON(data []byte) error { 319 if len(data) != 5 || data[0] != '"' || data[1] != 'Z' || data[4] != '"' { 320 return fmt.Errorf("bad quoted string") 321 } 322 i, err := strconv.ParseInt(string(data[2:4]), 16, 8) 323 if err != nil { 324 return fmt.Errorf("bad hex") 325 } 326 *b = intWithMarshalJSON(i) 327 return nil 328 } 329 330 type intWithPtrMarshalJSON int 331 332 func (b *intWithPtrMarshalJSON) MarshalJSON() ([]byte, error) { 333 return intWithMarshalJSON(*b).MarshalJSON() 334 } 335 336 func (b *intWithPtrMarshalJSON) UnmarshalJSON(data []byte) error { 337 return (*intWithMarshalJSON)(b).UnmarshalJSON(data) 338 } 339 340 type intWithMarshalText int 341 342 func (b intWithMarshalText) MarshalText() ([]byte, error) { 343 return []byte(fmt.Sprintf(`Z%.2x`, int(b))), nil 344 } 345 346 func (b *intWithMarshalText) UnmarshalText(data []byte) error { 347 if len(data) != 3 || data[0] != 'Z' { 348 return fmt.Errorf("bad quoted string") 349 } 350 i, err := strconv.ParseInt(string(data[1:3]), 16, 8) 351 if err != nil { 352 return fmt.Errorf("bad hex") 353 } 354 *b = intWithMarshalText(i) 355 return nil 356 } 357 358 type intWithPtrMarshalText int 359 360 func (b *intWithPtrMarshalText) MarshalText() ([]byte, error) { 361 return intWithMarshalText(*b).MarshalText() 362 } 363 364 func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error { 365 return (*intWithMarshalText)(b).UnmarshalText(data) 366 } 367 368 type unmarshalTest struct { 369 in string 370 ptr interface{} 371 out interface{} 372 err error 373 useNumber bool 374 golden bool 375 } 376 377 var unmarshalTests = []unmarshalTest{ 378 // basic types 379 {in: `true`, ptr: new(bool), out: true}, 380 {in: `1`, ptr: new(int), out: 1}, 381 {in: `1.2`, ptr: new(float64), out: 1.2}, 382 {in: `-5`, ptr: new(int16), out: int16(-5)}, 383 {in: `2`, ptr: new(Number), out: Number("2"), useNumber: true}, 384 {in: `2`, ptr: new(Number), out: Number("2")}, 385 {in: `2`, ptr: new(interface{}), out: float64(2.0)}, 386 {in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true}, 387 {in: `"a\u1234"`, ptr: new(string), out: "a\u1234"}, 388 {in: `"http:\/\/"`, ptr: new(string), out: "http://"}, 389 {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"}, 390 {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, 391 {in: "null", ptr: new(interface{}), out: nil}, 392 {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7}}, 393 {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, 394 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, 395 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true}, 396 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64}, 397 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true}, 398 399 // raw values with whitespace 400 {in: "\n true ", ptr: new(bool), out: true}, 401 {in: "\t 1 ", ptr: new(int), out: 1}, 402 {in: "\r 1.2 ", ptr: new(float64), out: 1.2}, 403 {in: "\t -5 \n", ptr: new(int16), out: int16(-5)}, 404 {in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"}, 405 406 // Z has a "-" tag. 407 {in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}}, 408 409 {in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 410 {in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 411 {in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}}, 412 413 // syntax errors 414 {in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}}, 415 {in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}}, 416 {in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true}, 417 418 // raw value errors 419 {in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 420 {in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}}, 421 {in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 422 {in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}}, 423 {in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 424 {in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}}, 425 {in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 426 {in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}}, 427 428 // array tests 429 {in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}}, 430 {in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}}, 431 {in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}}, 432 433 // empty array to interface test 434 {in: `[]`, ptr: new([]interface{}), out: []interface{}{}}, 435 {in: `null`, ptr: new([]interface{}), out: []interface{}(nil)}, 436 {in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}}, 437 {in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}}, 438 439 // composite tests 440 {in: allValueIndent, ptr: new(All), out: allValue}, 441 {in: allValueCompact, ptr: new(All), out: allValue}, 442 {in: allValueIndent, ptr: new(*All), out: &allValue}, 443 {in: allValueCompact, ptr: new(*All), out: &allValue}, 444 {in: pallValueIndent, ptr: new(All), out: pallValue}, 445 {in: pallValueCompact, ptr: new(All), out: pallValue}, 446 {in: pallValueIndent, ptr: new(*All), out: &pallValue}, 447 {in: pallValueCompact, ptr: new(*All), out: &pallValue}, 448 449 // unmarshal interface test 450 {in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called 451 {in: `{"T":false}`, ptr: &ump, out: &umtrue}, 452 {in: `[{"T":false}]`, ptr: &umslice, out: umslice}, 453 {in: `[{"T":false}]`, ptr: &umslicep, out: &umslice}, 454 {in: `{"M":{"T":"x:y"}}`, ptr: &umstruct, out: umstruct}, 455 456 // UnmarshalText interface test 457 {in: `"x:y"`, ptr: &um0T, out: umtrueXY}, 458 {in: `"x:y"`, ptr: &umpType, out: &umtrueXY}, 459 {in: `["x:y"]`, ptr: &umsliceXY, out: umsliceXY}, 460 {in: `["x:y"]`, ptr: &umslicepType, out: &umsliceXY}, 461 {in: `{"M":"x:y"}`, ptr: umstructType, out: umstructXY}, 462 463 // integer-keyed map test 464 { 465 in: `{"-1":"a","0":"b","1":"c"}`, 466 ptr: new(map[int]string), 467 out: map[int]string{-1: "a", 0: "b", 1: "c"}, 468 }, 469 { 470 in: `{"0":"a","10":"c","9":"b"}`, 471 ptr: new(map[u8]string), 472 out: map[u8]string{0: "a", 9: "b", 10: "c"}, 473 }, 474 { 475 in: `{"-9223372036854775808":"min","9223372036854775807":"max"}`, 476 ptr: new(map[int64]string), 477 out: map[int64]string{math.MinInt64: "min", math.MaxInt64: "max"}, 478 }, 479 { 480 in: `{"18446744073709551615":"max"}`, 481 ptr: new(map[uint64]string), 482 out: map[uint64]string{math.MaxUint64: "max"}, 483 }, 484 { 485 in: `{"0":false,"10":true}`, 486 ptr: new(map[uintptr]bool), 487 out: map[uintptr]bool{0: false, 10: true}, 488 }, 489 490 // Check that MarshalText and UnmarshalText take precedence 491 // over default integer handling in map keys. 492 { 493 in: `{"u2":4}`, 494 ptr: new(map[u8marshal]int), 495 out: map[u8marshal]int{2: 4}, 496 }, 497 { 498 in: `{"2":4}`, 499 ptr: new(map[u8marshal]int), 500 err: errMissingU8Prefix, 501 }, 502 503 // integer-keyed map errors 504 { 505 in: `{"abc":"abc"}`, 506 ptr: new(map[int]string), 507 err: &UnmarshalTypeError{"number abc", reflect.TypeOf(0), 2}, 508 }, 509 { 510 in: `{"256":"abc"}`, 511 ptr: new(map[uint8]string), 512 err: &UnmarshalTypeError{"number 256", reflect.TypeOf(uint8(0)), 2}, 513 }, 514 { 515 in: `{"128":"abc"}`, 516 ptr: new(map[int8]string), 517 err: &UnmarshalTypeError{"number 128", reflect.TypeOf(int8(0)), 2}, 518 }, 519 { 520 in: `{"-1":"abc"}`, 521 ptr: new(map[uint8]string), 522 err: &UnmarshalTypeError{"number -1", reflect.TypeOf(uint8(0)), 2}, 523 }, 524 525 // Map keys can be encoding.TextUnmarshalers. 526 {in: `{"x:y":true}`, ptr: &ummapType, out: ummapXY}, 527 // If multiple values for the same key exists, only the most recent value is used. 528 {in: `{"x:y":false,"x:y":true}`, ptr: &ummapType, out: ummapXY}, 529 530 // Overwriting of data. 531 // This is different from package xml, but it's what we've always done. 532 // Now documented and tested. 533 {in: `[2]`, ptr: sliceAddr([]int{1}), out: []int{2}}, 534 {in: `{"key": 2}`, ptr: mapAddr(map[string]int{"old": 0, "key": 1}), out: map[string]int{"key": 2}}, 535 536 { 537 in: `{ 538 "Level0": 1, 539 "Level1b": 2, 540 "Level1c": 3, 541 "x": 4, 542 "Level1a": 5, 543 "LEVEL1B": 6, 544 "e": { 545 "Level1a": 8, 546 "Level1b": 9, 547 "Level1c": 10, 548 "Level1d": 11, 549 "x": 12 550 }, 551 "Loop1": 13, 552 "Loop2": 14, 553 "X": 15, 554 "Y": 16, 555 "Z": 17, 556 "Q": 18 557 }`, 558 ptr: new(Top), 559 out: Top{ 560 Level0: 1, 561 Embed0: Embed0{ 562 Level1b: 2, 563 Level1c: 3, 564 }, 565 Embed0a: &Embed0a{ 566 Level1a: 5, 567 Level1b: 6, 568 }, 569 Embed0b: &Embed0b{ 570 Level1a: 8, 571 Level1b: 9, 572 Level1c: 10, 573 Level1d: 11, 574 Level1e: 12, 575 }, 576 Loop: Loop{ 577 Loop1: 13, 578 Loop2: 14, 579 }, 580 Embed0p: Embed0p{ 581 Point: image.Point{X: 15, Y: 16}, 582 }, 583 Embed0q: Embed0q{ 584 Point: Point{Z: 17}, 585 }, 586 embed: embed{ 587 Q: 18, 588 }, 589 }, 590 }, 591 { 592 in: `{"hello": 1}`, 593 ptr: new(Ambig), 594 out: Ambig{First: 1}, 595 }, 596 597 { 598 in: `{"X": 1,"Y":2}`, 599 ptr: new(S5), 600 out: S5{S8: S8{S9: S9{Y: 2}}}, 601 }, 602 { 603 in: `{"X": 1,"Y":2}`, 604 ptr: new(S10), 605 out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}}, 606 }, 607 608 // invalid UTF-8 is coerced to valid UTF-8. 609 { 610 in: "\"hello\xffworld\"", 611 ptr: new(string), 612 out: "hello\ufffdworld", 613 }, 614 { 615 in: "\"hello\xc2\xc2world\"", 616 ptr: new(string), 617 out: "hello\ufffd\ufffdworld", 618 }, 619 { 620 in: "\"hello\xc2\xffworld\"", 621 ptr: new(string), 622 out: "hello\ufffd\ufffdworld", 623 }, 624 { 625 in: "\"hello\\ud800world\"", 626 ptr: new(string), 627 out: "hello\ufffdworld", 628 }, 629 { 630 in: "\"hello\\ud800\\ud800world\"", 631 ptr: new(string), 632 out: "hello\ufffd\ufffdworld", 633 }, 634 { 635 in: "\"hello\\ud800\\ud800world\"", 636 ptr: new(string), 637 out: "hello\ufffd\ufffdworld", 638 }, 639 { 640 in: "\"hello\xed\xa0\x80\xed\xb0\x80world\"", 641 ptr: new(string), 642 out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld", 643 }, 644 645 // Used to be issue 8305, but time.Time implements encoding.TextUnmarshaler so this works now. 646 { 647 in: `{"2009-11-10T23:00:00Z": "hello world"}`, 648 ptr: &map[time.Time]string{}, 649 out: map[time.Time]string{time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC): "hello world"}, 650 }, 651 652 // issue 8305 653 { 654 in: `{"2009-11-10T23:00:00Z": "hello world"}`, 655 ptr: &map[Point]string{}, 656 err: &UnmarshalTypeError{"object", reflect.TypeOf(map[Point]string{}), 1}, 657 }, 658 { 659 in: `{"asdf": "hello world"}`, 660 ptr: &map[unmarshaler]string{}, 661 err: &UnmarshalTypeError{"object", reflect.TypeOf(map[unmarshaler]string{}), 1}, 662 }, 663 664 // related to issue 13783. 665 // Go 1.7 changed marshaling a slice of typed byte to use the methods on the byte type, 666 // similar to marshaling a slice of typed int. 667 // These tests check that, assuming the byte type also has valid decoding methods, 668 // either the old base64 string encoding or the new per-element encoding can be 669 // successfully unmarshaled. The custom unmarshalers were accessible in earlier 670 // versions of Go, even though the custom marshaler was not. 671 { 672 in: `"AQID"`, 673 ptr: new([]byteWithMarshalJSON), 674 out: []byteWithMarshalJSON{1, 2, 3}, 675 }, 676 { 677 in: `["Z01","Z02","Z03"]`, 678 ptr: new([]byteWithMarshalJSON), 679 out: []byteWithMarshalJSON{1, 2, 3}, 680 golden: true, 681 }, 682 { 683 in: `"AQID"`, 684 ptr: new([]byteWithMarshalText), 685 out: []byteWithMarshalText{1, 2, 3}, 686 }, 687 { 688 in: `["Z01","Z02","Z03"]`, 689 ptr: new([]byteWithMarshalText), 690 out: []byteWithMarshalText{1, 2, 3}, 691 golden: true, 692 }, 693 { 694 in: `"AQID"`, 695 ptr: new([]byteWithPtrMarshalJSON), 696 out: []byteWithPtrMarshalJSON{1, 2, 3}, 697 }, 698 { 699 in: `["Z01","Z02","Z03"]`, 700 ptr: new([]byteWithPtrMarshalJSON), 701 out: []byteWithPtrMarshalJSON{1, 2, 3}, 702 golden: true, 703 }, 704 { 705 in: `"AQID"`, 706 ptr: new([]byteWithPtrMarshalText), 707 out: []byteWithPtrMarshalText{1, 2, 3}, 708 }, 709 { 710 in: `["Z01","Z02","Z03"]`, 711 ptr: new([]byteWithPtrMarshalText), 712 out: []byteWithPtrMarshalText{1, 2, 3}, 713 golden: true, 714 }, 715 716 // ints work with the marshaler but not the base64 []byte case 717 { 718 in: `["Z01","Z02","Z03"]`, 719 ptr: new([]intWithMarshalJSON), 720 out: []intWithMarshalJSON{1, 2, 3}, 721 golden: true, 722 }, 723 { 724 in: `["Z01","Z02","Z03"]`, 725 ptr: new([]intWithMarshalText), 726 out: []intWithMarshalText{1, 2, 3}, 727 golden: true, 728 }, 729 { 730 in: `["Z01","Z02","Z03"]`, 731 ptr: new([]intWithPtrMarshalJSON), 732 out: []intWithPtrMarshalJSON{1, 2, 3}, 733 golden: true, 734 }, 735 { 736 in: `["Z01","Z02","Z03"]`, 737 ptr: new([]intWithPtrMarshalText), 738 out: []intWithPtrMarshalText{1, 2, 3}, 739 golden: true, 740 }, 741 } 742 743 func TestMarshal(t *testing.T) { 744 b, err := Marshal(allValue) 745 if err != nil { 746 t.Fatalf("Marshal allValue: %v", err) 747 } 748 if string(b) != allValueCompact { 749 t.Errorf("Marshal allValueCompact") 750 diff(t, b, []byte(allValueCompact)) 751 return 752 } 753 754 b, err = Marshal(pallValue) 755 if err != nil { 756 t.Fatalf("Marshal pallValue: %v", err) 757 } 758 if string(b) != pallValueCompact { 759 t.Errorf("Marshal pallValueCompact") 760 diff(t, b, []byte(pallValueCompact)) 761 return 762 } 763 } 764 765 var badUTF8 = []struct { 766 in, out string 767 }{ 768 {"hello\xffworld", `"hello\ufffdworld"`}, 769 {"", `""`}, 770 {"\xff", `"\ufffd"`}, 771 {"\xff\xff", `"\ufffd\ufffd"`}, 772 {"a\xffb", `"a\ufffdb"`}, 773 {"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`}, 774 } 775 776 func TestMarshalBadUTF8(t *testing.T) { 777 for _, tt := range badUTF8 { 778 b, err := Marshal(tt.in) 779 if string(b) != tt.out || err != nil { 780 t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out) 781 } 782 } 783 } 784 785 func TestMarshalNumberZeroVal(t *testing.T) { 786 var n Number 787 out, err := Marshal(n) 788 if err != nil { 789 t.Fatal(err) 790 } 791 outStr := string(out) 792 if outStr != "0" { 793 t.Fatalf("Invalid zero val for Number: %q", outStr) 794 } 795 } 796 797 func TestMarshalEmbeds(t *testing.T) { 798 top := &Top{ 799 Level0: 1, 800 Embed0: Embed0{ 801 Level1b: 2, 802 Level1c: 3, 803 }, 804 Embed0a: &Embed0a{ 805 Level1a: 5, 806 Level1b: 6, 807 }, 808 Embed0b: &Embed0b{ 809 Level1a: 8, 810 Level1b: 9, 811 Level1c: 10, 812 Level1d: 11, 813 Level1e: 12, 814 }, 815 Loop: Loop{ 816 Loop1: 13, 817 Loop2: 14, 818 }, 819 Embed0p: Embed0p{ 820 Point: image.Point{X: 15, Y: 16}, 821 }, 822 Embed0q: Embed0q{ 823 Point: Point{Z: 17}, 824 }, 825 embed: embed{ 826 Q: 18, 827 }, 828 } 829 b, err := Marshal(top) 830 if err != nil { 831 t.Fatal(err) 832 } 833 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,\"Q\":18}" 834 if string(b) != want { 835 t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want) 836 } 837 } 838 839 func TestUnmarshal(t *testing.T) { 840 for i, tt := range unmarshalTests { 841 var scan scanner 842 in := []byte(tt.in) 843 if err := checkValid(in, &scan); err != nil { 844 if !reflect.DeepEqual(err, tt.err) { 845 t.Errorf("#%d: checkValid: %#v", i, err) 846 continue 847 } 848 } 849 if tt.ptr == nil { 850 continue 851 } 852 853 // v = new(right-type) 854 v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 855 dec := NewDecoder(bytes.NewReader(in)) 856 if tt.useNumber { 857 dec.UseNumber() 858 } 859 if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) { 860 t.Errorf("#%d: %v, want %v", i, err, tt.err) 861 continue 862 } else if err != nil { 863 continue 864 } 865 if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { 866 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) 867 data, _ := Marshal(v.Elem().Interface()) 868 println(string(data)) 869 data, _ = Marshal(tt.out) 870 println(string(data)) 871 continue 872 } 873 874 // Check round trip also decodes correctly. 875 if tt.err == nil { 876 enc, err := Marshal(v.Interface()) 877 if err != nil { 878 t.Errorf("#%d: error re-marshaling: %v", i, err) 879 continue 880 } 881 if tt.golden && !bytes.Equal(enc, in) { 882 t.Errorf("#%d: remarshal mismatch:\nhave: %s\nwant: %s", i, enc, in) 883 } 884 vv := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 885 dec = NewDecoder(bytes.NewReader(enc)) 886 if tt.useNumber { 887 dec.UseNumber() 888 } 889 if err := dec.Decode(vv.Interface()); err != nil { 890 t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err) 891 continue 892 } 893 if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) { 894 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface()) 895 t.Errorf(" In: %q", strings.Map(noSpace, string(in))) 896 t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc))) 897 continue 898 } 899 } 900 } 901 } 902 903 func TestUnmarshalMarshal(t *testing.T) { 904 initBig() 905 var v interface{} 906 if err := Unmarshal(jsonBig, &v); err != nil { 907 t.Fatalf("Unmarshal: %v", err) 908 } 909 b, err := Marshal(v) 910 if err != nil { 911 t.Fatalf("Marshal: %v", err) 912 } 913 if !bytes.Equal(jsonBig, b) { 914 t.Errorf("Marshal jsonBig") 915 diff(t, b, jsonBig) 916 return 917 } 918 } 919 920 var numberTests = []struct { 921 in string 922 i int64 923 intErr string 924 f float64 925 floatErr string 926 }{ 927 {in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1}, 928 {in: "-12", i: -12, f: -12.0}, 929 {in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"}, 930 } 931 932 // Independent of Decode, basic coverage of the accessors in Number 933 func TestNumberAccessors(t *testing.T) { 934 for _, tt := range numberTests { 935 n := Number(tt.in) 936 if s := n.String(); s != tt.in { 937 t.Errorf("Number(%q).String() is %q", tt.in, s) 938 } 939 if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i { 940 t.Errorf("Number(%q).Int64() is %d", tt.in, i) 941 } else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) { 942 t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err) 943 } 944 if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f { 945 t.Errorf("Number(%q).Float64() is %g", tt.in, f) 946 } else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) { 947 t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err) 948 } 949 } 950 } 951 952 func TestLargeByteSlice(t *testing.T) { 953 s0 := make([]byte, 2000) 954 for i := range s0 { 955 s0[i] = byte(i) 956 } 957 b, err := Marshal(s0) 958 if err != nil { 959 t.Fatalf("Marshal: %v", err) 960 } 961 var s1 []byte 962 if err := Unmarshal(b, &s1); err != nil { 963 t.Fatalf("Unmarshal: %v", err) 964 } 965 if !bytes.Equal(s0, s1) { 966 t.Errorf("Marshal large byte slice") 967 diff(t, s0, s1) 968 } 969 } 970 971 type Xint struct { 972 X int 973 } 974 975 func TestUnmarshalInterface(t *testing.T) { 976 var xint Xint 977 var i interface{} = &xint 978 if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil { 979 t.Fatalf("Unmarshal: %v", err) 980 } 981 if xint.X != 1 { 982 t.Fatalf("Did not write to xint") 983 } 984 } 985 986 func TestUnmarshalPtrPtr(t *testing.T) { 987 var xint Xint 988 pxint := &xint 989 if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil { 990 t.Fatalf("Unmarshal: %v", err) 991 } 992 if xint.X != 1 { 993 t.Fatalf("Did not write to xint") 994 } 995 } 996 997 func TestEscape(t *testing.T) { 998 const input = `"foobar"<html>` + " [\u2028 \u2029]" 999 const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"` 1000 b, err := Marshal(input) 1001 if err != nil { 1002 t.Fatalf("Marshal error: %v", err) 1003 } 1004 if s := string(b); s != expected { 1005 t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected) 1006 } 1007 } 1008 1009 // WrongString is a struct that's misusing the ,string modifier. 1010 type WrongString struct { 1011 Message string `json:"result,string"` 1012 } 1013 1014 type wrongStringTest struct { 1015 in, err string 1016 } 1017 1018 var wrongStringTests = []wrongStringTest{ 1019 {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`}, 1020 {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`}, 1021 {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`}, 1022 {`{"result":123}`, `json: invalid use of ,string struct tag, trying to unmarshal unquoted value into string`}, 1023 } 1024 1025 // If people misuse the ,string modifier, the error message should be 1026 // helpful, telling the user that they're doing it wrong. 1027 func TestErrorMessageFromMisusedString(t *testing.T) { 1028 for n, tt := range wrongStringTests { 1029 r := strings.NewReader(tt.in) 1030 var s WrongString 1031 err := NewDecoder(r).Decode(&s) 1032 got := fmt.Sprintf("%v", err) 1033 if got != tt.err { 1034 t.Errorf("%d. got err = %q, want %q", n, got, tt.err) 1035 } 1036 } 1037 } 1038 1039 func noSpace(c rune) rune { 1040 if isSpace(byte(c)) { //only used for ascii 1041 return -1 1042 } 1043 return c 1044 } 1045 1046 type All struct { 1047 Bool bool 1048 Int int 1049 Int8 int8 1050 Int16 int16 1051 Int32 int32 1052 Int64 int64 1053 Uint uint 1054 Uint8 uint8 1055 Uint16 uint16 1056 Uint32 uint32 1057 Uint64 uint64 1058 Uintptr uintptr 1059 Float32 float32 1060 Float64 float64 1061 1062 Foo string `json:"bar"` 1063 Foo2 string `json:"bar2,dummyopt"` 1064 1065 IntStr int64 `json:",string"` 1066 1067 PBool *bool 1068 PInt *int 1069 PInt8 *int8 1070 PInt16 *int16 1071 PInt32 *int32 1072 PInt64 *int64 1073 PUint *uint 1074 PUint8 *uint8 1075 PUint16 *uint16 1076 PUint32 *uint32 1077 PUint64 *uint64 1078 PUintptr *uintptr 1079 PFloat32 *float32 1080 PFloat64 *float64 1081 1082 String string 1083 PString *string 1084 1085 Map map[string]Small 1086 MapP map[string]*Small 1087 PMap *map[string]Small 1088 PMapP *map[string]*Small 1089 1090 EmptyMap map[string]Small 1091 NilMap map[string]Small 1092 1093 Slice []Small 1094 SliceP []*Small 1095 PSlice *[]Small 1096 PSliceP *[]*Small 1097 1098 EmptySlice []Small 1099 NilSlice []Small 1100 1101 StringSlice []string 1102 ByteSlice []byte 1103 1104 Small Small 1105 PSmall *Small 1106 PPSmall **Small 1107 1108 Interface interface{} 1109 PInterface *interface{} 1110 1111 unexported int 1112 } 1113 1114 type Small struct { 1115 Tag string 1116 } 1117 1118 var allValue = All{ 1119 Bool: true, 1120 Int: 2, 1121 Int8: 3, 1122 Int16: 4, 1123 Int32: 5, 1124 Int64: 6, 1125 Uint: 7, 1126 Uint8: 8, 1127 Uint16: 9, 1128 Uint32: 10, 1129 Uint64: 11, 1130 Uintptr: 12, 1131 Float32: 14.1, 1132 Float64: 15.1, 1133 Foo: "foo", 1134 Foo2: "foo2", 1135 IntStr: 42, 1136 String: "16", 1137 Map: map[string]Small{ 1138 "17": {Tag: "tag17"}, 1139 "18": {Tag: "tag18"}, 1140 }, 1141 MapP: map[string]*Small{ 1142 "19": {Tag: "tag19"}, 1143 "20": nil, 1144 }, 1145 EmptyMap: map[string]Small{}, 1146 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, 1147 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, 1148 EmptySlice: []Small{}, 1149 StringSlice: []string{"str24", "str25", "str26"}, 1150 ByteSlice: []byte{27, 28, 29}, 1151 Small: Small{Tag: "tag30"}, 1152 PSmall: &Small{Tag: "tag31"}, 1153 Interface: 5.2, 1154 } 1155 1156 var pallValue = All{ 1157 PBool: &allValue.Bool, 1158 PInt: &allValue.Int, 1159 PInt8: &allValue.Int8, 1160 PInt16: &allValue.Int16, 1161 PInt32: &allValue.Int32, 1162 PInt64: &allValue.Int64, 1163 PUint: &allValue.Uint, 1164 PUint8: &allValue.Uint8, 1165 PUint16: &allValue.Uint16, 1166 PUint32: &allValue.Uint32, 1167 PUint64: &allValue.Uint64, 1168 PUintptr: &allValue.Uintptr, 1169 PFloat32: &allValue.Float32, 1170 PFloat64: &allValue.Float64, 1171 PString: &allValue.String, 1172 PMap: &allValue.Map, 1173 PMapP: &allValue.MapP, 1174 PSlice: &allValue.Slice, 1175 PSliceP: &allValue.SliceP, 1176 PPSmall: &allValue.PSmall, 1177 PInterface: &allValue.Interface, 1178 } 1179 1180 var allValueIndent = `{ 1181 "Bool": true, 1182 "Int": 2, 1183 "Int8": 3, 1184 "Int16": 4, 1185 "Int32": 5, 1186 "Int64": 6, 1187 "Uint": 7, 1188 "Uint8": 8, 1189 "Uint16": 9, 1190 "Uint32": 10, 1191 "Uint64": 11, 1192 "Uintptr": 12, 1193 "Float32": 14.1, 1194 "Float64": 15.1, 1195 "bar": "foo", 1196 "bar2": "foo2", 1197 "IntStr": "42", 1198 "PBool": null, 1199 "PInt": null, 1200 "PInt8": null, 1201 "PInt16": null, 1202 "PInt32": null, 1203 "PInt64": null, 1204 "PUint": null, 1205 "PUint8": null, 1206 "PUint16": null, 1207 "PUint32": null, 1208 "PUint64": null, 1209 "PUintptr": null, 1210 "PFloat32": null, 1211 "PFloat64": null, 1212 "String": "16", 1213 "PString": null, 1214 "Map": { 1215 "17": { 1216 "Tag": "tag17" 1217 }, 1218 "18": { 1219 "Tag": "tag18" 1220 } 1221 }, 1222 "MapP": { 1223 "19": { 1224 "Tag": "tag19" 1225 }, 1226 "20": null 1227 }, 1228 "PMap": null, 1229 "PMapP": null, 1230 "EmptyMap": {}, 1231 "NilMap": null, 1232 "Slice": [ 1233 { 1234 "Tag": "tag20" 1235 }, 1236 { 1237 "Tag": "tag21" 1238 } 1239 ], 1240 "SliceP": [ 1241 { 1242 "Tag": "tag22" 1243 }, 1244 null, 1245 { 1246 "Tag": "tag23" 1247 } 1248 ], 1249 "PSlice": null, 1250 "PSliceP": null, 1251 "EmptySlice": [], 1252 "NilSlice": null, 1253 "StringSlice": [ 1254 "str24", 1255 "str25", 1256 "str26" 1257 ], 1258 "ByteSlice": "Gxwd", 1259 "Small": { 1260 "Tag": "tag30" 1261 }, 1262 "PSmall": { 1263 "Tag": "tag31" 1264 }, 1265 "PPSmall": null, 1266 "Interface": 5.2, 1267 "PInterface": null 1268 }` 1269 1270 var allValueCompact = strings.Map(noSpace, allValueIndent) 1271 1272 var pallValueIndent = `{ 1273 "Bool": false, 1274 "Int": 0, 1275 "Int8": 0, 1276 "Int16": 0, 1277 "Int32": 0, 1278 "Int64": 0, 1279 "Uint": 0, 1280 "Uint8": 0, 1281 "Uint16": 0, 1282 "Uint32": 0, 1283 "Uint64": 0, 1284 "Uintptr": 0, 1285 "Float32": 0, 1286 "Float64": 0, 1287 "bar": "", 1288 "bar2": "", 1289 "IntStr": "0", 1290 "PBool": true, 1291 "PInt": 2, 1292 "PInt8": 3, 1293 "PInt16": 4, 1294 "PInt32": 5, 1295 "PInt64": 6, 1296 "PUint": 7, 1297 "PUint8": 8, 1298 "PUint16": 9, 1299 "PUint32": 10, 1300 "PUint64": 11, 1301 "PUintptr": 12, 1302 "PFloat32": 14.1, 1303 "PFloat64": 15.1, 1304 "String": "", 1305 "PString": "16", 1306 "Map": null, 1307 "MapP": null, 1308 "PMap": { 1309 "17": { 1310 "Tag": "tag17" 1311 }, 1312 "18": { 1313 "Tag": "tag18" 1314 } 1315 }, 1316 "PMapP": { 1317 "19": { 1318 "Tag": "tag19" 1319 }, 1320 "20": null 1321 }, 1322 "EmptyMap": null, 1323 "NilMap": null, 1324 "Slice": null, 1325 "SliceP": null, 1326 "PSlice": [ 1327 { 1328 "Tag": "tag20" 1329 }, 1330 { 1331 "Tag": "tag21" 1332 } 1333 ], 1334 "PSliceP": [ 1335 { 1336 "Tag": "tag22" 1337 }, 1338 null, 1339 { 1340 "Tag": "tag23" 1341 } 1342 ], 1343 "EmptySlice": null, 1344 "NilSlice": null, 1345 "StringSlice": null, 1346 "ByteSlice": null, 1347 "Small": { 1348 "Tag": "" 1349 }, 1350 "PSmall": null, 1351 "PPSmall": { 1352 "Tag": "tag31" 1353 }, 1354 "Interface": null, 1355 "PInterface": 5.2 1356 }` 1357 1358 var pallValueCompact = strings.Map(noSpace, pallValueIndent) 1359 1360 func TestRefUnmarshal(t *testing.T) { 1361 type S struct { 1362 // Ref is defined in encode_test.go. 1363 R0 Ref 1364 R1 *Ref 1365 R2 RefText 1366 R3 *RefText 1367 } 1368 want := S{ 1369 R0: 12, 1370 R1: new(Ref), 1371 R2: 13, 1372 R3: new(RefText), 1373 } 1374 *want.R1 = 12 1375 *want.R3 = 13 1376 1377 var got S 1378 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil { 1379 t.Fatalf("Unmarshal: %v", err) 1380 } 1381 if !reflect.DeepEqual(got, want) { 1382 t.Errorf("got %+v, want %+v", got, want) 1383 } 1384 } 1385 1386 // Test that the empty string doesn't panic decoding when ,string is specified 1387 // Issue 3450 1388 func TestEmptyString(t *testing.T) { 1389 type T2 struct { 1390 Number1 int `json:",string"` 1391 Number2 int `json:",string"` 1392 } 1393 data := `{"Number1":"1", "Number2":""}` 1394 dec := NewDecoder(strings.NewReader(data)) 1395 var t2 T2 1396 err := dec.Decode(&t2) 1397 if err == nil { 1398 t.Fatal("Decode: did not return error") 1399 } 1400 if t2.Number1 != 1 { 1401 t.Fatal("Decode: did not set Number1") 1402 } 1403 } 1404 1405 // Test that a null for ,string is not replaced with the previous quoted string (issue 7046). 1406 // It should also not be an error (issue 2540, issue 8587). 1407 func TestNullString(t *testing.T) { 1408 type T struct { 1409 A int `json:",string"` 1410 B int `json:",string"` 1411 C *int `json:",string"` 1412 } 1413 data := []byte(`{"A": "1", "B": null, "C": null}`) 1414 var s T 1415 s.B = 1 1416 s.C = new(int) 1417 *s.C = 2 1418 err := Unmarshal(data, &s) 1419 if err != nil { 1420 t.Fatalf("Unmarshal: %v", err) 1421 } 1422 if s.B != 1 || s.C != nil { 1423 t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C) 1424 } 1425 } 1426 1427 func intp(x int) *int { 1428 p := new(int) 1429 *p = x 1430 return p 1431 } 1432 1433 func intpp(x *int) **int { 1434 pp := new(*int) 1435 *pp = x 1436 return pp 1437 } 1438 1439 var interfaceSetTests = []struct { 1440 pre interface{} 1441 json string 1442 post interface{} 1443 }{ 1444 {"foo", `"bar"`, "bar"}, 1445 {"foo", `2`, 2.0}, 1446 {"foo", `true`, true}, 1447 {"foo", `null`, nil}, 1448 1449 {nil, `null`, nil}, 1450 {new(int), `null`, nil}, 1451 {(*int)(nil), `null`, nil}, 1452 {new(*int), `null`, new(*int)}, 1453 {(**int)(nil), `null`, nil}, 1454 {intp(1), `null`, nil}, 1455 {intpp(nil), `null`, intpp(nil)}, 1456 {intpp(intp(1)), `null`, intpp(nil)}, 1457 } 1458 1459 func TestInterfaceSet(t *testing.T) { 1460 for _, tt := range interfaceSetTests { 1461 b := struct{ X interface{} }{tt.pre} 1462 blob := `{"X":` + tt.json + `}` 1463 if err := Unmarshal([]byte(blob), &b); err != nil { 1464 t.Errorf("Unmarshal %#q: %v", blob, err) 1465 continue 1466 } 1467 if !reflect.DeepEqual(b.X, tt.post) { 1468 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post) 1469 } 1470 } 1471 } 1472 1473 // JSON null values should be ignored for primitives and string values instead of resulting in an error. 1474 // Issue 2540 1475 func TestUnmarshalNulls(t *testing.T) { 1476 jsonData := []byte(`{ 1477 "Bool" : null, 1478 "Int" : null, 1479 "Int8" : null, 1480 "Int16" : null, 1481 "Int32" : null, 1482 "Int64" : null, 1483 "Uint" : null, 1484 "Uint8" : null, 1485 "Uint16" : null, 1486 "Uint32" : null, 1487 "Uint64" : null, 1488 "Float32" : null, 1489 "Float64" : null, 1490 "String" : null}`) 1491 1492 nulls := All{ 1493 Bool: true, 1494 Int: 2, 1495 Int8: 3, 1496 Int16: 4, 1497 Int32: 5, 1498 Int64: 6, 1499 Uint: 7, 1500 Uint8: 8, 1501 Uint16: 9, 1502 Uint32: 10, 1503 Uint64: 11, 1504 Float32: 12.1, 1505 Float64: 13.1, 1506 String: "14"} 1507 1508 err := Unmarshal(jsonData, &nulls) 1509 if err != nil { 1510 t.Errorf("Unmarshal of null values failed: %v", err) 1511 } 1512 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 || 1513 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 || 1514 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" { 1515 1516 t.Errorf("Unmarshal of null values affected primitives") 1517 } 1518 } 1519 1520 func TestStringKind(t *testing.T) { 1521 type stringKind string 1522 1523 var m1, m2 map[stringKind]int 1524 m1 = map[stringKind]int{ 1525 "foo": 42, 1526 } 1527 1528 data, err := Marshal(m1) 1529 if err != nil { 1530 t.Errorf("Unexpected error marshaling: %v", err) 1531 } 1532 1533 err = Unmarshal(data, &m2) 1534 if err != nil { 1535 t.Errorf("Unexpected error unmarshaling: %v", err) 1536 } 1537 1538 if !reflect.DeepEqual(m1, m2) { 1539 t.Error("Items should be equal after encoding and then decoding") 1540 } 1541 } 1542 1543 // Custom types with []byte as underlying type could not be marshalled 1544 // and then unmarshalled. 1545 // Issue 8962. 1546 func TestByteKind(t *testing.T) { 1547 type byteKind []byte 1548 1549 a := byteKind("hello") 1550 1551 data, err := Marshal(a) 1552 if err != nil { 1553 t.Error(err) 1554 } 1555 var b byteKind 1556 err = Unmarshal(data, &b) 1557 if err != nil { 1558 t.Fatal(err) 1559 } 1560 if !reflect.DeepEqual(a, b) { 1561 t.Errorf("expected %v == %v", a, b) 1562 } 1563 } 1564 1565 // The fix for issue 8962 introduced a regression. 1566 // Issue 12921. 1567 func TestSliceOfCustomByte(t *testing.T) { 1568 type Uint8 uint8 1569 1570 a := []Uint8("hello") 1571 1572 data, err := Marshal(a) 1573 if err != nil { 1574 t.Fatal(err) 1575 } 1576 var b []Uint8 1577 err = Unmarshal(data, &b) 1578 if err != nil { 1579 t.Fatal(err) 1580 } 1581 if !reflect.DeepEqual(a, b) { 1582 t.Fatalf("expected %v == %v", a, b) 1583 } 1584 } 1585 1586 var decodeTypeErrorTests = []struct { 1587 dest interface{} 1588 src string 1589 }{ 1590 {new(string), `{"user": "name"}`}, // issue 4628. 1591 {new(error), `{}`}, // issue 4222 1592 {new(error), `[]`}, 1593 {new(error), `""`}, 1594 {new(error), `123`}, 1595 {new(error), `true`}, 1596 } 1597 1598 func TestUnmarshalTypeError(t *testing.T) { 1599 for _, item := range decodeTypeErrorTests { 1600 err := Unmarshal([]byte(item.src), item.dest) 1601 if _, ok := err.(*UnmarshalTypeError); !ok { 1602 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", 1603 item.src, item.dest, err) 1604 } 1605 } 1606 } 1607 1608 var unmarshalSyntaxTests = []string{ 1609 "tru", 1610 "fals", 1611 "nul", 1612 "123e", 1613 `"hello`, 1614 `[1,2,3`, 1615 `{"key":1`, 1616 `{"key":1,`, 1617 } 1618 1619 func TestUnmarshalSyntax(t *testing.T) { 1620 var x interface{} 1621 for _, src := range unmarshalSyntaxTests { 1622 err := Unmarshal([]byte(src), &x) 1623 if _, ok := err.(*SyntaxError); !ok { 1624 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) 1625 } 1626 } 1627 } 1628 1629 // Test handling of unexported fields that should be ignored. 1630 // Issue 4660 1631 type unexportedFields struct { 1632 Name string 1633 m map[string]interface{} `json:"-"` 1634 m2 map[string]interface{} `json:"abcd"` 1635 } 1636 1637 func TestUnmarshalUnexported(t *testing.T) { 1638 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}` 1639 want := &unexportedFields{Name: "Bob"} 1640 1641 out := &unexportedFields{} 1642 err := Unmarshal([]byte(input), out) 1643 if err != nil { 1644 t.Errorf("got error %v, expected nil", err) 1645 } 1646 if !reflect.DeepEqual(out, want) { 1647 t.Errorf("got %q, want %q", out, want) 1648 } 1649 } 1650 1651 // Time3339 is a time.Time which encodes to and from JSON 1652 // as an RFC 3339 time in UTC. 1653 type Time3339 time.Time 1654 1655 func (t *Time3339) UnmarshalJSON(b []byte) error { 1656 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { 1657 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) 1658 } 1659 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) 1660 if err != nil { 1661 return err 1662 } 1663 *t = Time3339(tm) 1664 return nil 1665 } 1666 1667 func TestUnmarshalJSONLiteralError(t *testing.T) { 1668 var t3 Time3339 1669 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) 1670 if err == nil { 1671 t.Fatalf("expected error; got time %v", time.Time(t3)) 1672 } 1673 if !strings.Contains(err.Error(), "range") { 1674 t.Errorf("got err = %v; want out of range error", err) 1675 } 1676 } 1677 1678 // Test that extra object elements in an array do not result in a 1679 // "data changing underfoot" error. 1680 // Issue 3717 1681 func TestSkipArrayObjects(t *testing.T) { 1682 json := `[{}]` 1683 var dest [0]interface{} 1684 1685 err := Unmarshal([]byte(json), &dest) 1686 if err != nil { 1687 t.Errorf("got error %q, want nil", err) 1688 } 1689 } 1690 1691 // Test semantics of pre-filled struct fields and pre-filled map fields. 1692 // Issue 4900. 1693 func TestPrefilled(t *testing.T) { 1694 ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m } 1695 1696 // Values here change, cannot reuse table across runs. 1697 var prefillTests = []struct { 1698 in string 1699 ptr interface{} 1700 out interface{} 1701 }{ 1702 { 1703 in: `{"X": 1, "Y": 2}`, 1704 ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5}, 1705 out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5}, 1706 }, 1707 { 1708 in: `{"X": 1, "Y": 2}`, 1709 ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}), 1710 out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}), 1711 }, 1712 } 1713 1714 for _, tt := range prefillTests { 1715 ptrstr := fmt.Sprintf("%v", tt.ptr) 1716 err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here 1717 if err != nil { 1718 t.Errorf("Unmarshal: %v", err) 1719 } 1720 if !reflect.DeepEqual(tt.ptr, tt.out) { 1721 t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out) 1722 } 1723 } 1724 } 1725 1726 var invalidUnmarshalTests = []struct { 1727 v interface{} 1728 want string 1729 }{ 1730 {nil, "json: Unmarshal(nil)"}, 1731 {struct{}{}, "json: Unmarshal(non-pointer struct {})"}, 1732 {(*int)(nil), "json: Unmarshal(nil *int)"}, 1733 } 1734 1735 func TestInvalidUnmarshal(t *testing.T) { 1736 buf := []byte(`{"a":"1"}`) 1737 for _, tt := range invalidUnmarshalTests { 1738 err := Unmarshal(buf, tt.v) 1739 if err == nil { 1740 t.Errorf("Unmarshal expecting error, got nil") 1741 continue 1742 } 1743 if got := err.Error(); got != tt.want { 1744 t.Errorf("Unmarshal = %q; want %q", got, tt.want) 1745 } 1746 } 1747 } 1748 1749 var invalidUnmarshalTextTests = []struct { 1750 v interface{} 1751 want string 1752 }{ 1753 {nil, "json: Unmarshal(nil)"}, 1754 {struct{}{}, "json: Unmarshal(non-pointer struct {})"}, 1755 {(*int)(nil), "json: Unmarshal(nil *int)"}, 1756 {new(net.IP), "json: cannot unmarshal string into Go value of type *net.IP"}, 1757 } 1758 1759 func TestInvalidUnmarshalText(t *testing.T) { 1760 buf := []byte(`123`) 1761 for _, tt := range invalidUnmarshalTextTests { 1762 err := Unmarshal(buf, tt.v) 1763 if err == nil { 1764 t.Errorf("Unmarshal expecting error, got nil") 1765 continue 1766 } 1767 if got := err.Error(); got != tt.want { 1768 t.Errorf("Unmarshal = %q; want %q", got, tt.want) 1769 } 1770 } 1771 } 1772 1773 // Test that string option is ignored for invalid types. 1774 // Issue 9812. 1775 func TestInvalidStringOption(t *testing.T) { 1776 num := 0 1777 item := struct { 1778 T time.Time `json:",string"` 1779 M map[string]string `json:",string"` 1780 S []string `json:",string"` 1781 A [1]string `json:",string"` 1782 I interface{} `json:",string"` 1783 P *int `json:",string"` 1784 }{M: make(map[string]string), S: make([]string, 0), I: num, P: &num} 1785 1786 data, err := Marshal(item) 1787 if err != nil { 1788 t.Fatalf("Marshal: %v", err) 1789 } 1790 1791 err = Unmarshal(data, &item) 1792 if err != nil { 1793 t.Fatalf("Unmarshal: %v", err) 1794 } 1795 }