git.lukeshu.com/go/lowmemjson@v0.3.9-0.20230723050957-72f6d13f6fb2/compat/json/borrowed_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 // SPDX-License-Identifier: BSD-3-Clause 6 7 package json 8 9 import ( 10 "bytes" 11 "encoding" 12 "errors" 13 "fmt" 14 "image" 15 "math" 16 "math/big" 17 "net" 18 "reflect" 19 "strconv" 20 "strings" 21 "testing" 22 "time" 23 ) 24 25 type T struct { 26 X string 27 Y int 28 Z int `json:"-"` 29 } 30 31 type U struct { 32 Alphabet string `json:"alpha"` 33 } 34 35 type V struct { 36 F1 any 37 F2 int32 38 F3 Number 39 F4 *VOuter 40 } 41 42 type VOuter struct { 43 V V 44 } 45 46 type W struct { 47 S SS 48 } 49 50 type P struct { 51 PP PP 52 } 53 54 type PP struct { 55 T T 56 Ts []T 57 } 58 59 type SS string 60 61 func (*SS) UnmarshalJSON(data []byte) error { 62 return &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(SS(""))} 63 } 64 65 // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and 66 // without UseNumber 67 var ifaceNumAsFloat64 = map[string]any{ 68 "k1": float64(1), 69 "k2": "s", 70 "k3": []any{float64(1), float64(2.0), float64(3e-3)}, 71 "k4": map[string]any{"kk1": "s", "kk2": float64(2)}, 72 } 73 74 var ifaceNumAsNumber = map[string]any{ 75 "k1": Number("1"), 76 "k2": "s", 77 "k3": []any{Number("1"), Number("2.0"), Number("3e-3")}, 78 "k4": map[string]any{"kk1": "s", "kk2": Number("2")}, 79 } 80 81 type tx struct { 82 x int //nolint:unused // it is used, but only via reflection // MODIFIED: added nolint annotation 83 } 84 85 type u8 uint8 86 87 // A type that can unmarshal itself. 88 89 type unmarshaler struct { 90 T bool 91 } 92 93 func (u *unmarshaler) UnmarshalJSON(b []byte) error { 94 *u = unmarshaler{true} // All we need to see that UnmarshalJSON is called. 95 return nil 96 } 97 98 type ustruct struct { 99 M unmarshaler 100 } 101 102 type unmarshalerText struct { 103 A, B string 104 } 105 106 // needed for re-marshaling tests 107 func (u unmarshalerText) MarshalText() ([]byte, error) { 108 return []byte(u.A + ":" + u.B), nil 109 } 110 111 func (u *unmarshalerText) UnmarshalText(b []byte) error { 112 pos := bytes.IndexByte(b, ':') 113 if pos == -1 { 114 return errors.New("missing separator") 115 } 116 u.A, u.B = string(b[:pos]), string(b[pos+1:]) 117 return nil 118 } 119 120 var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil) 121 122 type ustructText struct { 123 M unmarshalerText 124 } 125 126 // u8marshal is an integer type that can marshal/unmarshal itself. 127 type u8marshal uint8 128 129 func (u8 u8marshal) MarshalText() ([]byte, error) { 130 return []byte(fmt.Sprintf("u%d", u8)), nil 131 } 132 133 var errMissingU8Prefix = errors.New("missing 'u' prefix") 134 135 func (u8 *u8marshal) UnmarshalText(b []byte) error { 136 if !bytes.HasPrefix(b, []byte{'u'}) { 137 return errMissingU8Prefix 138 } 139 n, err := strconv.Atoi(string(b[1:])) 140 if err != nil { 141 return err 142 } 143 *u8 = u8marshal(n) 144 return nil 145 } 146 147 var _ encoding.TextUnmarshaler = (*u8marshal)(nil) 148 149 var ( 150 umtrue = unmarshaler{true} 151 umslice = []unmarshaler{{true}} 152 umstruct = ustruct{unmarshaler{true}} 153 154 umtrueXY = unmarshalerText{"x", "y"} 155 umsliceXY = []unmarshalerText{{"x", "y"}} 156 umstructXY = ustructText{unmarshalerText{"x", "y"}} 157 158 ummapXY = map[unmarshalerText]bool{{"x", "y"}: true} 159 ) 160 161 // Test data structures for anonymous fields. 162 163 type Point struct { 164 Z int 165 } 166 167 type Top struct { 168 Level0 int 169 Embed0 170 *Embed0a 171 *Embed0b `json:"e,omitempty"` // treated as named 172 Embed0c `json:"-"` // ignored 173 Loop 174 Embed0p // has Point with X, Y, used 175 Embed0q // has Point with Z, used 176 embed // contains exported field 177 } 178 179 type Embed0 struct { 180 Level1a int // overridden by Embed0a's Level1a with json tag 181 Level1b int // used because Embed0a's Level1b is renamed 182 Level1c int // used because Embed0a's Level1c is ignored 183 Level1d int // annihilated by Embed0a's Level1d 184 Level1e int `json:"x"` // annihilated by Embed0a.Level1e 185 } 186 187 type Embed0a struct { 188 Level1a int `json:"Level1a,omitempty"` 189 Level1b int `json:"LEVEL1B,omitempty"` 190 Level1c int `json:"-"` 191 Level1d int // annihilated by Embed0's Level1d 192 Level1f int `json:"x"` // annihilated by Embed0's Level1e 193 } 194 195 type Embed0b Embed0 196 197 type Embed0c Embed0 198 199 type Embed0p struct { 200 image.Point 201 } 202 203 type Embed0q struct { 204 Point 205 } 206 207 type embed struct { 208 Q int 209 } 210 211 type Loop struct { 212 Loop1 int `json:",omitempty"` 213 Loop2 int `json:",omitempty"` 214 *Loop 215 } 216 217 // From reflect test: 218 // The X in S6 and S7 annihilate, but they also block the X in S8.S9. 219 type S5 struct { 220 S6 221 S7 222 S8 223 } 224 225 type S6 struct { 226 X int 227 } 228 229 type S7 S6 230 231 type S8 struct { 232 S9 233 } 234 235 type S9 struct { 236 X int 237 Y int 238 } 239 240 // From reflect test: 241 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9. 242 type S10 struct { 243 S11 244 S12 245 S13 246 } 247 248 type S11 struct { 249 S6 250 } 251 252 type S12 struct { 253 S6 254 } 255 256 type S13 struct { 257 S8 258 } 259 260 type Ambig struct { 261 // Given "hello", the first match should win. 262 First int `json:"HELLO"` 263 Second int `json:"Hello"` 264 } 265 266 type XYZ struct { 267 X any 268 Y any 269 Z any 270 } 271 272 type unexportedWithMethods struct{} 273 274 func (unexportedWithMethods) F() {} 275 276 type byteWithMarshalJSON byte 277 278 func (b byteWithMarshalJSON) MarshalJSON() ([]byte, error) { 279 return []byte(fmt.Sprintf(`"Z%.2x"`, byte(b))), nil 280 } 281 282 func (b *byteWithMarshalJSON) UnmarshalJSON(data []byte) error { 283 if len(data) != 5 || data[0] != '"' || data[1] != 'Z' || data[4] != '"' { 284 return fmt.Errorf("bad quoted string") 285 } 286 i, err := strconv.ParseInt(string(data[2:4]), 16, 8) 287 if err != nil { 288 return fmt.Errorf("bad hex") 289 } 290 *b = byteWithMarshalJSON(i) 291 return nil 292 } 293 294 type byteWithPtrMarshalJSON byte 295 296 func (b *byteWithPtrMarshalJSON) MarshalJSON() ([]byte, error) { 297 return byteWithMarshalJSON(*b).MarshalJSON() 298 } 299 300 func (b *byteWithPtrMarshalJSON) UnmarshalJSON(data []byte) error { 301 return (*byteWithMarshalJSON)(b).UnmarshalJSON(data) 302 } 303 304 type byteWithMarshalText byte 305 306 func (b byteWithMarshalText) MarshalText() ([]byte, error) { 307 return []byte(fmt.Sprintf(`Z%.2x`, byte(b))), nil 308 } 309 310 func (b *byteWithMarshalText) UnmarshalText(data []byte) error { 311 if len(data) != 3 || data[0] != 'Z' { 312 return fmt.Errorf("bad quoted string") 313 } 314 i, err := strconv.ParseInt(string(data[1:3]), 16, 8) 315 if err != nil { 316 return fmt.Errorf("bad hex") 317 } 318 *b = byteWithMarshalText(i) 319 return nil 320 } 321 322 type byteWithPtrMarshalText byte 323 324 func (b *byteWithPtrMarshalText) MarshalText() ([]byte, error) { 325 return byteWithMarshalText(*b).MarshalText() 326 } 327 328 func (b *byteWithPtrMarshalText) UnmarshalText(data []byte) error { 329 return (*byteWithMarshalText)(b).UnmarshalText(data) 330 } 331 332 type intWithMarshalJSON int 333 334 func (b intWithMarshalJSON) MarshalJSON() ([]byte, error) { 335 return []byte(fmt.Sprintf(`"Z%.2x"`, int(b))), nil 336 } 337 338 func (b *intWithMarshalJSON) UnmarshalJSON(data []byte) error { 339 if len(data) != 5 || data[0] != '"' || data[1] != 'Z' || data[4] != '"' { 340 return fmt.Errorf("bad quoted string") 341 } 342 i, err := strconv.ParseInt(string(data[2:4]), 16, 8) 343 if err != nil { 344 return fmt.Errorf("bad hex") 345 } 346 *b = intWithMarshalJSON(i) 347 return nil 348 } 349 350 type intWithPtrMarshalJSON int 351 352 func (b *intWithPtrMarshalJSON) MarshalJSON() ([]byte, error) { 353 return intWithMarshalJSON(*b).MarshalJSON() 354 } 355 356 func (b *intWithPtrMarshalJSON) UnmarshalJSON(data []byte) error { 357 return (*intWithMarshalJSON)(b).UnmarshalJSON(data) 358 } 359 360 type intWithMarshalText int 361 362 func (b intWithMarshalText) MarshalText() ([]byte, error) { 363 return []byte(fmt.Sprintf(`Z%.2x`, int(b))), nil 364 } 365 366 func (b *intWithMarshalText) UnmarshalText(data []byte) error { 367 if len(data) != 3 || data[0] != 'Z' { 368 return fmt.Errorf("bad quoted string") 369 } 370 i, err := strconv.ParseInt(string(data[1:3]), 16, 8) 371 if err != nil { 372 return fmt.Errorf("bad hex") 373 } 374 *b = intWithMarshalText(i) 375 return nil 376 } 377 378 type intWithPtrMarshalText int 379 380 func (b *intWithPtrMarshalText) MarshalText() ([]byte, error) { 381 return intWithMarshalText(*b).MarshalText() 382 } 383 384 func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error { 385 return (*intWithMarshalText)(b).UnmarshalText(data) 386 } 387 388 type mapStringToStringData struct { 389 Data map[string]string `json:"data"` 390 } 391 392 type unmarshalTest struct { 393 in string 394 ptr any // new(type) 395 out any 396 err error 397 useNumber bool 398 golden bool 399 disallowUnknownFields bool 400 } 401 402 type B struct { 403 B bool `json:",string"` 404 } 405 406 type DoublePtr struct { 407 I **int 408 J **int 409 } 410 411 var unmarshalTests = []unmarshalTest{ 412 // basic types 413 {in: `true`, ptr: new(bool), out: true}, 414 {in: `1`, ptr: new(int), out: 1}, 415 {in: `1.2`, ptr: new(float64), out: 1.2}, 416 {in: `-5`, ptr: new(int16), out: int16(-5)}, 417 {in: `2`, ptr: new(Number), out: Number("2"), useNumber: true}, 418 {in: `2`, ptr: new(Number), out: Number("2")}, 419 {in: `2`, ptr: new(any), out: float64(2.0)}, 420 {in: `2`, ptr: new(any), out: Number("2"), useNumber: true}, 421 {in: `"a\u1234"`, ptr: new(string), out: "a\u1234"}, 422 {in: `"http:\/\/"`, ptr: new(string), out: "http://"}, 423 {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"}, 424 {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, 425 {in: "null", ptr: new(any), out: nil}, 426 {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{Value: "array", Type: reflect.TypeOf(""), Offset: 7, Struct: "T", Field: "X"}}, // MODIFIED: don't use unkeyed fields (govet) 427 {in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 8, Struct: "T", Field: "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, // MODIFIED: don't use unkeyed fields (govet) 428 {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, 429 {in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true}, 430 {in: `{"S": 23}`, ptr: new(W), out: W{}, err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(SS("")), Offset: 0, Struct: "W", Field: "S"}}, // MODIFIED: don't use unkeyed fields (govet) 431 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, 432 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true}, 433 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(any), out: ifaceNumAsFloat64}, 434 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(any), out: ifaceNumAsNumber, useNumber: true}, 435 436 // raw values with whitespace 437 {in: "\n true ", ptr: new(bool), out: true}, 438 {in: "\t 1 ", ptr: new(int), out: 1}, 439 {in: "\r 1.2 ", ptr: new(float64), out: 1.2}, 440 {in: "\t -5 \n", ptr: new(int16), out: int16(-5)}, 441 {in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"}, 442 443 // Z has a "-" tag. 444 {in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}}, 445 {in: `{"Y": 1, "Z": 2}`, ptr: new(T), err: fmt.Errorf("json: unknown field \"Z\""), disallowUnknownFields: true}, 446 447 {in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 448 {in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), err: fmt.Errorf("json: unknown field \"alphabet\""), disallowUnknownFields: true}, 449 {in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 450 {in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}}, 451 {in: `{"alphabet": "xyz"}`, ptr: new(U), err: fmt.Errorf("json: unknown field \"alphabet\""), disallowUnknownFields: true}, 452 453 // syntax errors 454 {in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}}, 455 {in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}}, 456 {in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true}, 457 {in: `[2, 3`, err: &SyntaxError{msg: "unexpected end of JSON input", Offset: 5}}, 458 {in: `{"F3": -}`, ptr: new(V), out: V{F3: Number("-")}, err: &SyntaxError{msg: "invalid character '}' in numeric literal", Offset: 9}}, 459 460 // raw value errors 461 {in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 462 {in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}}, 463 {in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 464 {in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}}, 465 {in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 466 {in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}}, 467 {in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 468 {in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}}, 469 470 // array tests 471 {in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}}, 472 {in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}}, 473 {in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}}, 474 {in: `[1, 2, 3]`, ptr: new(MustNotUnmarshalJSON), err: errors.New("MustNotUnmarshalJSON was used")}, 475 476 // empty array to interface test 477 {in: `[]`, ptr: new([]any), out: []any{}}, 478 {in: `null`, ptr: new([]any), out: []any(nil)}, 479 {in: `{"T":[]}`, ptr: new(map[string]any), out: map[string]any{"T": []any{}}}, 480 {in: `{"T":null}`, ptr: new(map[string]any), out: map[string]any{"T": any(nil)}}, 481 482 // composite tests 483 {in: allValueIndent, ptr: new(All), out: allValue}, 484 {in: allValueCompact, ptr: new(All), out: allValue}, 485 {in: allValueIndent, ptr: new(*All), out: &allValue}, 486 {in: allValueCompact, ptr: new(*All), out: &allValue}, 487 {in: pallValueIndent, ptr: new(All), out: pallValue}, 488 {in: pallValueCompact, ptr: new(All), out: pallValue}, 489 {in: pallValueIndent, ptr: new(*All), out: &pallValue}, 490 {in: pallValueCompact, ptr: new(*All), out: &pallValue}, 491 492 // unmarshal interface test 493 {in: `{"T":false}`, ptr: new(unmarshaler), out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called 494 {in: `{"T":false}`, ptr: new(*unmarshaler), out: &umtrue}, 495 {in: `[{"T":false}]`, ptr: new([]unmarshaler), out: umslice}, 496 {in: `[{"T":false}]`, ptr: new(*[]unmarshaler), out: &umslice}, 497 {in: `{"M":{"T":"x:y"}}`, ptr: new(ustruct), out: umstruct}, 498 499 // UnmarshalText interface test 500 {in: `"x:y"`, ptr: new(unmarshalerText), out: umtrueXY}, 501 {in: `"x:y"`, ptr: new(*unmarshalerText), out: &umtrueXY}, 502 {in: `["x:y"]`, ptr: new([]unmarshalerText), out: umsliceXY}, 503 {in: `["x:y"]`, ptr: new(*[]unmarshalerText), out: &umsliceXY}, 504 {in: `{"M":"x:y"}`, ptr: new(ustructText), out: umstructXY}, 505 506 // integer-keyed map test 507 { 508 in: `{"-1":"a","0":"b","1":"c"}`, 509 ptr: new(map[int]string), 510 out: map[int]string{-1: "a", 0: "b", 1: "c"}, 511 }, 512 { 513 in: `{"0":"a","10":"c","9":"b"}`, 514 ptr: new(map[u8]string), 515 out: map[u8]string{0: "a", 9: "b", 10: "c"}, 516 }, 517 { 518 in: `{"-9223372036854775808":"min","9223372036854775807":"max"}`, 519 ptr: new(map[int64]string), 520 out: map[int64]string{math.MinInt64: "min", math.MaxInt64: "max"}, 521 }, 522 { 523 in: `{"18446744073709551615":"max"}`, 524 ptr: new(map[uint64]string), 525 out: map[uint64]string{math.MaxUint64: "max"}, 526 }, 527 { 528 in: `{"0":false,"10":true}`, 529 ptr: new(map[uintptr]bool), 530 out: map[uintptr]bool{0: false, 10: true}, 531 }, 532 533 // Check that MarshalText and UnmarshalText take precedence 534 // over default integer handling in map keys. 535 { 536 in: `{"u2":4}`, 537 ptr: new(map[u8marshal]int), 538 out: map[u8marshal]int{2: 4}, 539 }, 540 { 541 in: `{"2":4}`, 542 ptr: new(map[u8marshal]int), 543 err: errMissingU8Prefix, 544 }, 545 546 // integer-keyed map errors 547 { 548 in: `{"abc":"abc"}`, 549 ptr: new(map[int]string), 550 err: &UnmarshalTypeError{Value: "number abc", Type: reflect.TypeOf(0), Offset: 2}, 551 }, 552 { 553 in: `{"256":"abc"}`, 554 ptr: new(map[uint8]string), 555 err: &UnmarshalTypeError{Value: "number 256", Type: reflect.TypeOf(uint8(0)), Offset: 2}, 556 }, 557 { 558 in: `{"128":"abc"}`, 559 ptr: new(map[int8]string), 560 err: &UnmarshalTypeError{Value: "number 128", Type: reflect.TypeOf(int8(0)), Offset: 2}, 561 }, 562 { 563 in: `{"-1":"abc"}`, 564 ptr: new(map[uint8]string), 565 err: &UnmarshalTypeError{Value: "number -1", Type: reflect.TypeOf(uint8(0)), Offset: 2}, 566 }, 567 { 568 in: `{"F":{"a":2,"3":4}}`, 569 ptr: new(map[string]map[int]int), 570 err: &UnmarshalTypeError{Value: "number a", Type: reflect.TypeOf(int(0)), Offset: 7}, 571 }, 572 { 573 in: `{"F":{"a":2,"3":4}}`, 574 ptr: new(map[string]map[uint]int), 575 err: &UnmarshalTypeError{Value: "number a", Type: reflect.TypeOf(uint(0)), Offset: 7}, 576 }, 577 578 // Map keys can be encoding.TextUnmarshalers. 579 {in: `{"x:y":true}`, ptr: new(map[unmarshalerText]bool), out: ummapXY}, 580 // If multiple values for the same key exists, only the most recent value is used. 581 {in: `{"x:y":false,"x:y":true}`, ptr: new(map[unmarshalerText]bool), out: ummapXY}, 582 583 { 584 in: `{ 585 "Level0": 1, 586 "Level1b": 2, 587 "Level1c": 3, 588 "x": 4, 589 "Level1a": 5, 590 "LEVEL1B": 6, 591 "e": { 592 "Level1a": 8, 593 "Level1b": 9, 594 "Level1c": 10, 595 "Level1d": 11, 596 "x": 12 597 }, 598 "Loop1": 13, 599 "Loop2": 14, 600 "X": 15, 601 "Y": 16, 602 "Z": 17, 603 "Q": 18 604 }`, 605 ptr: new(Top), 606 out: Top{ 607 Level0: 1, 608 Embed0: Embed0{ 609 Level1b: 2, 610 Level1c: 3, 611 }, 612 Embed0a: &Embed0a{ 613 Level1a: 5, 614 Level1b: 6, 615 }, 616 Embed0b: &Embed0b{ 617 Level1a: 8, 618 Level1b: 9, 619 Level1c: 10, 620 Level1d: 11, 621 Level1e: 12, 622 }, 623 Loop: Loop{ 624 Loop1: 13, 625 Loop2: 14, 626 }, 627 Embed0p: Embed0p{ 628 Point: image.Point{X: 15, Y: 16}, 629 }, 630 Embed0q: Embed0q{ 631 Point: Point{Z: 17}, 632 }, 633 embed: embed{ 634 Q: 18, 635 }, 636 }, 637 }, 638 { 639 in: `{"hello": 1}`, 640 ptr: new(Ambig), 641 out: Ambig{First: 1}, 642 }, 643 644 { 645 in: `{"X": 1,"Y":2}`, 646 ptr: new(S5), 647 out: S5{S8: S8{S9: S9{Y: 2}}}, 648 }, 649 { 650 in: `{"X": 1,"Y":2}`, 651 ptr: new(S5), 652 err: fmt.Errorf("json: unknown field \"X\""), 653 disallowUnknownFields: true, 654 }, 655 { 656 in: `{"X": 1,"Y":2}`, 657 ptr: new(S10), 658 out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}}, 659 }, 660 { 661 in: `{"X": 1,"Y":2}`, 662 ptr: new(S10), 663 err: fmt.Errorf("json: unknown field \"X\""), 664 disallowUnknownFields: true, 665 }, 666 { 667 in: `{"I": 0, "I": null, "J": null}`, 668 ptr: new(DoublePtr), 669 out: DoublePtr{I: nil, J: nil}, 670 }, 671 672 // invalid UTF-8 is coerced to valid UTF-8. 673 { 674 in: "\"hello\xffworld\"", 675 ptr: new(string), 676 out: "hello\ufffdworld", 677 }, 678 { 679 in: "\"hello\xc2\xc2world\"", 680 ptr: new(string), 681 out: "hello\ufffd\ufffdworld", 682 }, 683 { 684 in: "\"hello\xc2\xffworld\"", 685 ptr: new(string), 686 out: "hello\ufffd\ufffdworld", 687 }, 688 { 689 in: "\"hello\\ud800world\"", 690 ptr: new(string), 691 out: "hello\ufffdworld", 692 }, 693 { 694 in: "\"hello\\ud800\\ud800world\"", 695 ptr: new(string), 696 out: "hello\ufffd\ufffdworld", 697 }, 698 { 699 in: "\"hello\\ud800\\ud800world\"", 700 ptr: new(string), 701 out: "hello\ufffd\ufffdworld", 702 }, 703 { 704 in: "\"hello\xed\xa0\x80\xed\xb0\x80world\"", 705 ptr: new(string), 706 out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld", 707 }, 708 709 // Used to be issue 8305, but time.Time implements encoding.TextUnmarshaler so this works now. 710 { 711 in: `{"2009-11-10T23:00:00Z": "hello world"}`, 712 ptr: new(map[time.Time]string), 713 out: map[time.Time]string{time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC): "hello world"}, 714 }, 715 716 // issue 8305 717 { 718 in: `{"2009-11-10T23:00:00Z": "hello world"}`, 719 ptr: new(map[Point]string), 720 err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(map[Point]string{}), Offset: 1}, 721 }, 722 { 723 in: `{"asdf": "hello world"}`, 724 ptr: new(map[unmarshaler]string), 725 err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(map[unmarshaler]string{}), Offset: 1}, 726 }, 727 728 // related to issue 13783. 729 // Go 1.7 changed marshaling a slice of typed byte to use the methods on the byte type, 730 // similar to marshaling a slice of typed int. 731 // These tests check that, assuming the byte type also has valid decoding methods, 732 // either the old base64 string encoding or the new per-element encoding can be 733 // successfully unmarshaled. The custom unmarshalers were accessible in earlier 734 // versions of Go, even though the custom marshaler was not. 735 { 736 in: `"AQID"`, 737 ptr: new([]byteWithMarshalJSON), 738 out: []byteWithMarshalJSON{1, 2, 3}, 739 }, 740 { 741 in: `["Z01","Z02","Z03"]`, 742 ptr: new([]byteWithMarshalJSON), 743 out: []byteWithMarshalJSON{1, 2, 3}, 744 golden: true, 745 }, 746 { 747 in: `"AQID"`, 748 ptr: new([]byteWithMarshalText), 749 out: []byteWithMarshalText{1, 2, 3}, 750 }, 751 { 752 in: `["Z01","Z02","Z03"]`, 753 ptr: new([]byteWithMarshalText), 754 out: []byteWithMarshalText{1, 2, 3}, 755 golden: true, 756 }, 757 { 758 in: `"AQID"`, 759 ptr: new([]byteWithPtrMarshalJSON), 760 out: []byteWithPtrMarshalJSON{1, 2, 3}, 761 }, 762 { 763 in: `["Z01","Z02","Z03"]`, 764 ptr: new([]byteWithPtrMarshalJSON), 765 out: []byteWithPtrMarshalJSON{1, 2, 3}, 766 golden: true, 767 }, 768 { 769 in: `"AQID"`, 770 ptr: new([]byteWithPtrMarshalText), 771 out: []byteWithPtrMarshalText{1, 2, 3}, 772 }, 773 { 774 in: `["Z01","Z02","Z03"]`, 775 ptr: new([]byteWithPtrMarshalText), 776 out: []byteWithPtrMarshalText{1, 2, 3}, 777 golden: true, 778 }, 779 780 // ints work with the marshaler but not the base64 []byte case 781 { 782 in: `["Z01","Z02","Z03"]`, 783 ptr: new([]intWithMarshalJSON), 784 out: []intWithMarshalJSON{1, 2, 3}, 785 golden: true, 786 }, 787 { 788 in: `["Z01","Z02","Z03"]`, 789 ptr: new([]intWithMarshalText), 790 out: []intWithMarshalText{1, 2, 3}, 791 golden: true, 792 }, 793 { 794 in: `["Z01","Z02","Z03"]`, 795 ptr: new([]intWithPtrMarshalJSON), 796 out: []intWithPtrMarshalJSON{1, 2, 3}, 797 golden: true, 798 }, 799 { 800 in: `["Z01","Z02","Z03"]`, 801 ptr: new([]intWithPtrMarshalText), 802 out: []intWithPtrMarshalText{1, 2, 3}, 803 golden: true, 804 }, 805 806 {in: `0.000001`, ptr: new(float64), out: 0.000001, golden: true}, 807 {in: `1e-7`, ptr: new(float64), out: 1e-7, golden: true}, 808 {in: `100000000000000000000`, ptr: new(float64), out: 100000000000000000000.0, golden: true}, 809 {in: `1e+21`, ptr: new(float64), out: 1e21, golden: true}, 810 {in: `-0.000001`, ptr: new(float64), out: -0.000001, golden: true}, 811 {in: `-1e-7`, ptr: new(float64), out: -1e-7, golden: true}, 812 {in: `-100000000000000000000`, ptr: new(float64), out: -100000000000000000000.0, golden: true}, 813 {in: `-1e+21`, ptr: new(float64), out: -1e21, golden: true}, 814 {in: `999999999999999900000`, ptr: new(float64), out: 999999999999999900000.0, golden: true}, 815 {in: `9007199254740992`, ptr: new(float64), out: 9007199254740992.0, golden: true}, 816 {in: `9007199254740993`, ptr: new(float64), out: 9007199254740992.0, golden: false}, 817 818 { 819 in: `{"V": {"F2": "hello"}}`, 820 ptr: new(VOuter), 821 err: &UnmarshalTypeError{ 822 Value: "string", 823 Struct: "V", 824 Field: "V.F2", 825 Type: reflect.TypeOf(int32(0)), 826 Offset: 20, 827 }, 828 }, 829 { 830 in: `{"V": {"F4": {}, "F2": "hello"}}`, 831 ptr: new(VOuter), 832 err: &UnmarshalTypeError{ 833 Value: "string", 834 Struct: "V", 835 Field: "V.F2", 836 Type: reflect.TypeOf(int32(0)), 837 Offset: 30, 838 }, 839 }, 840 841 // issue 15146. 842 // invalid inputs in wrongStringTests below. 843 {in: `{"B":"true"}`, ptr: new(B), out: B{true}, golden: true}, 844 {in: `{"B":"false"}`, ptr: new(B), out: B{false}, golden: true}, 845 {in: `{"B": "maybe"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "maybe" into bool`)}, 846 {in: `{"B": "tru"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "tru" into bool`)}, 847 {in: `{"B": "False"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "False" into bool`)}, 848 {in: `{"B": "null"}`, ptr: new(B), out: B{false}}, 849 {in: `{"B": "nul"}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal "nul" into bool`)}, 850 {in: `{"B": [2, 3]}`, ptr: new(B), err: errors.New(`json: invalid use of ,string struct tag, trying to unmarshal unquoted value into bool`)}, 851 852 // additional tests for disallowUnknownFields 853 { 854 in: `{ 855 "Level0": 1, 856 "Level1b": 2, 857 "Level1c": 3, 858 "x": 4, 859 "Level1a": 5, 860 "LEVEL1B": 6, 861 "e": { 862 "Level1a": 8, 863 "Level1b": 9, 864 "Level1c": 10, 865 "Level1d": 11, 866 "x": 12 867 }, 868 "Loop1": 13, 869 "Loop2": 14, 870 "X": 15, 871 "Y": 16, 872 "Z": 17, 873 "Q": 18, 874 "extra": true 875 }`, 876 ptr: new(Top), 877 err: fmt.Errorf("json: unknown field \"extra\""), 878 disallowUnknownFields: true, 879 }, 880 { 881 in: `{ 882 "Level0": 1, 883 "Level1b": 2, 884 "Level1c": 3, 885 "x": 4, 886 "Level1a": 5, 887 "LEVEL1B": 6, 888 "e": { 889 "Level1a": 8, 890 "Level1b": 9, 891 "Level1c": 10, 892 "Level1d": 11, 893 "x": 12, 894 "extra": null 895 }, 896 "Loop1": 13, 897 "Loop2": 14, 898 "X": 15, 899 "Y": 16, 900 "Z": 17, 901 "Q": 18 902 }`, 903 ptr: new(Top), 904 err: fmt.Errorf("json: unknown field \"extra\""), 905 disallowUnknownFields: true, 906 }, 907 // issue 26444 908 // UnmarshalTypeError without field & struct values 909 { 910 in: `{"data":{"test1": "bob", "test2": 123}}`, 911 ptr: new(mapStringToStringData), 912 err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 37, Struct: "mapStringToStringData", Field: "data"}, 913 }, 914 { 915 in: `{"data":{"test1": 123, "test2": "bob"}}`, 916 ptr: new(mapStringToStringData), 917 err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 21, Struct: "mapStringToStringData", Field: "data"}, 918 }, 919 920 // trying to decode JSON arrays or objects via TextUnmarshaler 921 { 922 in: `[1, 2, 3]`, 923 ptr: new(MustNotUnmarshalText), 924 err: &UnmarshalTypeError{Value: "array", Type: reflect.TypeOf(&MustNotUnmarshalText{}), Offset: 1}, 925 }, 926 { 927 in: `{"foo": "bar"}`, 928 ptr: new(MustNotUnmarshalText), 929 err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(&MustNotUnmarshalText{}), Offset: 1}, 930 }, 931 // #22369 932 { 933 in: `{"PP": {"T": {"Y": "bad-type"}}}`, 934 ptr: new(P), 935 err: &UnmarshalTypeError{ 936 Value: "string", 937 Struct: "T", 938 Field: "PP.T.Y", 939 Type: reflect.TypeOf(int(0)), 940 Offset: 29, 941 }, 942 }, 943 { 944 in: `{"Ts": [{"Y": 1}, {"Y": 2}, {"Y": "bad-type"}]}`, 945 ptr: new(PP), 946 err: &UnmarshalTypeError{ 947 Value: "string", 948 Struct: "T", 949 Field: "Ts.Y", 950 Type: reflect.TypeOf(int(0)), 951 Offset: 29, 952 }, 953 }, 954 // #14702 955 { 956 in: `invalid`, 957 ptr: new(Number), 958 err: &SyntaxError{ 959 msg: "invalid character 'i' looking for beginning of value", 960 Offset: 1, 961 }, 962 }, 963 { 964 in: `"invalid"`, 965 ptr: new(Number), 966 err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), 967 }, 968 { 969 in: `{"A":"invalid"}`, 970 ptr: new(struct{ A Number }), 971 err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), 972 }, 973 { 974 in: `{"A":"invalid"}`, 975 ptr: new(struct { 976 A Number `json:",string"` 977 }), 978 err: fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into json.Number", `invalid`), 979 }, 980 { 981 in: `{"A":"invalid"}`, 982 ptr: new(map[string]Number), 983 err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), 984 }, 985 } 986 987 func TestMarshal(t *testing.T) { 988 t.Parallel() // MODIFIED: added 989 b, err := Marshal(allValue) 990 if err != nil { 991 t.Fatalf("Marshal allValue: %v", err) 992 } 993 if string(b) != allValueCompact { 994 t.Errorf("Marshal allValueCompact") 995 diff(t, b, []byte(allValueCompact)) 996 return 997 } 998 999 b, err = Marshal(pallValue) 1000 if err != nil { 1001 t.Fatalf("Marshal pallValue: %v", err) 1002 } 1003 if string(b) != pallValueCompact { 1004 t.Errorf("Marshal pallValueCompact") 1005 diff(t, b, []byte(pallValueCompact)) 1006 return 1007 } 1008 } 1009 1010 var badUTF8 = []struct { 1011 in, out string 1012 }{ 1013 {"hello\xffworld", `"hello\ufffdworld"`}, 1014 {"", `""`}, 1015 {"\xff", `"\ufffd"`}, 1016 {"\xff\xff", `"\ufffd\ufffd"`}, 1017 {"a\xffb", `"a\ufffdb"`}, 1018 {"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`}, 1019 } 1020 1021 func TestMarshalBadUTF8(t *testing.T) { 1022 t.Parallel() // MODIFIED: added 1023 for _, tt := range badUTF8 { 1024 b, err := Marshal(tt.in) 1025 if string(b) != tt.out || err != nil { 1026 t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out) 1027 } 1028 } 1029 } 1030 1031 func TestMarshalNumberZeroVal(t *testing.T) { 1032 t.Parallel() // MODIFIED: added 1033 var n Number 1034 out, err := Marshal(n) 1035 if err != nil { 1036 t.Fatal(err) 1037 } 1038 outStr := string(out) 1039 if outStr != "0" { 1040 t.Fatalf("Invalid zero val for Number: %q", outStr) 1041 } 1042 } 1043 1044 func TestMarshalEmbeds(t *testing.T) { 1045 t.Parallel() // MODIFIED: added 1046 top := &Top{ 1047 Level0: 1, 1048 Embed0: Embed0{ 1049 Level1b: 2, 1050 Level1c: 3, 1051 }, 1052 Embed0a: &Embed0a{ 1053 Level1a: 5, 1054 Level1b: 6, 1055 }, 1056 Embed0b: &Embed0b{ 1057 Level1a: 8, 1058 Level1b: 9, 1059 Level1c: 10, 1060 Level1d: 11, 1061 Level1e: 12, 1062 }, 1063 Loop: Loop{ 1064 Loop1: 13, 1065 Loop2: 14, 1066 }, 1067 Embed0p: Embed0p{ 1068 Point: image.Point{X: 15, Y: 16}, 1069 }, 1070 Embed0q: Embed0q{ 1071 Point: Point{Z: 17}, 1072 }, 1073 embed: embed{ 1074 Q: 18, 1075 }, 1076 } 1077 b, err := Marshal(top) 1078 if err != nil { 1079 t.Fatal(err) 1080 } 1081 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}" 1082 if string(b) != want { 1083 t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want) 1084 } 1085 } 1086 1087 func equalError(a, b error) bool { 1088 if a == nil { 1089 return b == nil 1090 } 1091 if b == nil { 1092 return a == nil 1093 } 1094 return a.Error() == b.Error() 1095 } 1096 1097 func TestUnmarshal(t *testing.T) { 1098 t.Parallel() // MODIFIED: added 1099 for i, tt := range unmarshalTests { 1100 var scan scanner 1101 in := []byte(tt.in) 1102 var expSyntaxError error // MODIFIED: added 1103 if _, ok := tt.err.(*SyntaxError); ok { // MODIFIED: added 1104 expSyntaxError = tt.err // MODIFIED: added 1105 } // MODIFIED: added 1106 if err := checkValid(in, &scan); !equalError(err, expSyntaxError) { // MODIFIED: don't ignore cases where it returned nil but should have returned an error 1107 t.Errorf("#%d: checkValid:\n got: %#v\nwant: %#v", i, err, expSyntaxError) // MODIFIED: show what the expected error was 1108 continue 1109 } 1110 if tt.ptr == nil { 1111 var val any // MODIFIED: added 1112 if err := Unmarshal([]byte(tt.in), &val); !equalError(err, expSyntaxError) { // MODIFIED: added 1113 t.Errorf("#%d: Unmarshal:\n got: %#v\nwant: %#v", i, err, expSyntaxError) // MODIFIED: added 1114 } // MODIFIED: added 1115 continue 1116 } 1117 1118 typ := reflect.TypeOf(tt.ptr) 1119 if typ.Kind() != reflect.Pointer { 1120 t.Errorf("#%d: unmarshalTest.ptr %T is not a pointer type", i, tt.ptr) 1121 continue 1122 } 1123 typ = typ.Elem() 1124 1125 // v = new(right-type) 1126 v := reflect.New(typ) 1127 1128 if !reflect.DeepEqual(tt.ptr, v.Interface()) { 1129 // There's no reason for ptr to point to non-zero data, 1130 // as we decode into new(right-type), so the data is 1131 // discarded. 1132 // This can easily mean tests that silently don't test 1133 // what they should. To test decoding into existing 1134 // data, see TestPrefilled. 1135 t.Errorf("#%d: unmarshalTest.ptr %#v is not a pointer to a zero value", i, tt.ptr) 1136 continue 1137 } 1138 1139 dec := NewDecoder(bytes.NewReader(in)) 1140 if tt.useNumber { 1141 dec.UseNumber() 1142 } 1143 if tt.disallowUnknownFields { 1144 dec.DisallowUnknownFields() 1145 } 1146 if err := dec.Decode(v.Interface()); !equalError(err, tt.err) { 1147 t.Errorf("#%d: %v, want %v", i, err, tt.err) 1148 continue 1149 } else if err != nil { 1150 continue 1151 } 1152 if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { 1153 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) 1154 data, _ := Marshal(v.Elem().Interface()) 1155 t.Log(string(data)) // MODIFIED: use the test logger 1156 data, _ = Marshal(tt.out) 1157 t.Log(string(data)) // MODIFIED: use the test logger 1158 continue 1159 } 1160 1161 // Check round trip also decodes correctly. 1162 if tt.err == nil { 1163 enc, err := Marshal(v.Interface()) 1164 if err != nil { 1165 t.Errorf("#%d: error re-marshaling: %v", i, err) 1166 continue 1167 } 1168 if tt.golden && !bytes.Equal(enc, in) { 1169 t.Errorf("#%d: remarshal mismatch:\nhave: %s\nwant: %s", i, enc, in) 1170 } 1171 vv := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 1172 dec = NewDecoder(bytes.NewReader(enc)) 1173 if tt.useNumber { 1174 dec.UseNumber() 1175 } 1176 if err := dec.Decode(vv.Interface()); err != nil { 1177 t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err) 1178 continue 1179 } 1180 if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) { 1181 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface()) 1182 t.Errorf(" In: %q", strings.Map(noSpace, string(in))) 1183 t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc))) 1184 continue 1185 } 1186 } 1187 } 1188 } 1189 1190 func TestUnmarshalMarshal(t *testing.T) { 1191 t.Parallel() // MODIFIED: added 1192 initBig() 1193 var v any 1194 if err := Unmarshal(jsonBig, &v); err != nil { 1195 t.Fatalf("Unmarshal: %v", err) 1196 } 1197 b, err := Marshal(v) 1198 if err != nil { 1199 t.Fatalf("Marshal: %v", err) 1200 } 1201 if !bytes.Equal(jsonBig, b) { 1202 t.Errorf("Marshal jsonBig") 1203 diff(t, b, jsonBig) 1204 return 1205 } 1206 } 1207 1208 var numberTests = []struct { 1209 in string 1210 i int64 1211 intErr string 1212 f float64 1213 floatErr string 1214 }{ 1215 {in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1}, 1216 {in: "-12", i: -12, f: -12.0}, 1217 {in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"}, 1218 } 1219 1220 // Independent of Decode, basic coverage of the accessors in Number 1221 func TestNumberAccessors(t *testing.T) { 1222 t.Parallel() // MODIFIED: added 1223 for _, tt := range numberTests { 1224 n := Number(tt.in) 1225 if s := n.String(); s != tt.in { 1226 t.Errorf("Number(%q).String() is %q", tt.in, s) 1227 } 1228 if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i { 1229 t.Errorf("Number(%q).Int64() is %d", tt.in, i) 1230 } else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) { 1231 t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err) 1232 } 1233 if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f { 1234 t.Errorf("Number(%q).Float64() is %g", tt.in, f) 1235 } else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) { 1236 t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err) 1237 } 1238 } 1239 } 1240 1241 func TestLargeByteSlice(t *testing.T) { 1242 t.Parallel() // MODIFIED: added 1243 s0 := make([]byte, 2000) 1244 for i := range s0 { 1245 s0[i] = byte(i) 1246 } 1247 b, err := Marshal(s0) 1248 if err != nil { 1249 t.Fatalf("Marshal: %v", err) 1250 } 1251 var s1 []byte 1252 if err := Unmarshal(b, &s1); err != nil { 1253 t.Fatalf("Unmarshal: %v", err) 1254 } 1255 if !bytes.Equal(s0, s1) { 1256 t.Errorf("Marshal large byte slice") 1257 diff(t, s0, s1) 1258 } 1259 } 1260 1261 type Xint struct { 1262 X int 1263 } 1264 1265 func TestUnmarshalInterface(t *testing.T) { 1266 t.Parallel() // MODIFIED: added 1267 var xint Xint 1268 var i any = &xint 1269 if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil { 1270 t.Fatalf("Unmarshal: %v", err) 1271 } 1272 if xint.X != 1 { 1273 t.Fatalf("Did not write to xint") 1274 } 1275 } 1276 1277 func TestUnmarshalPtrPtr(t *testing.T) { 1278 t.Parallel() // MODIFIED: added 1279 var xint Xint 1280 pxint := &xint 1281 if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil { 1282 t.Fatalf("Unmarshal: %v", err) 1283 } 1284 if xint.X != 1 { 1285 t.Fatalf("Did not write to xint") 1286 } 1287 } 1288 1289 func TestEscape(t *testing.T) { 1290 t.Parallel() // MODIFIED: added 1291 const input = `"foobar"<html>` + " [\u2028 \u2029]" 1292 const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"` 1293 b, err := Marshal(input) 1294 if err != nil { 1295 t.Fatalf("Marshal error: %v", err) 1296 } 1297 if s := string(b); s != expected { 1298 t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected) 1299 } 1300 } 1301 1302 // WrongString is a struct that's misusing the ,string modifier. 1303 type WrongString struct { 1304 Message string `json:"result,string"` 1305 } 1306 1307 type wrongStringTest struct { 1308 in, err string 1309 } 1310 1311 var wrongStringTests = []wrongStringTest{ 1312 {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`}, 1313 {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`}, 1314 {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`}, 1315 {`{"result":123}`, `json: invalid use of ,string struct tag, trying to unmarshal unquoted value into string`}, 1316 {`{"result":"\""}`, `json: invalid use of ,string struct tag, trying to unmarshal "\"" into string`}, 1317 {`{"result":"\"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "\"foo" into string`}, 1318 } 1319 1320 // If people misuse the ,string modifier, the error message should be 1321 // helpful, telling the user that they're doing it wrong. 1322 func TestErrorMessageFromMisusedString(t *testing.T) { 1323 t.Parallel() // MODIFIED: added 1324 for n, tt := range wrongStringTests { 1325 r := strings.NewReader(tt.in) 1326 var s WrongString 1327 err := NewDecoder(r).Decode(&s) 1328 got := fmt.Sprintf("%v", err) 1329 if got != tt.err { 1330 t.Errorf("%d. got err = %q, want %q", n, got, tt.err) 1331 } 1332 } 1333 } 1334 1335 func noSpace(c rune) rune { 1336 if isSpace(byte(c)) { //only used for ascii 1337 return -1 1338 } 1339 return c 1340 } 1341 1342 type All struct { 1343 Bool bool 1344 Int int 1345 Int8 int8 1346 Int16 int16 1347 Int32 int32 1348 Int64 int64 1349 Uint uint 1350 Uint8 uint8 1351 Uint16 uint16 1352 Uint32 uint32 1353 Uint64 uint64 1354 Uintptr uintptr 1355 Float32 float32 1356 Float64 float64 1357 1358 Foo string `json:"bar"` 1359 Foo2 string `json:"bar2,dummyopt"` //nolint:staticcheck // testing handling of unknown options // MODIFIED: added nolint annotation 1360 1361 IntStr int64 `json:",string"` 1362 UintptrStr uintptr `json:",string"` 1363 1364 PBool *bool 1365 PInt *int 1366 PInt8 *int8 1367 PInt16 *int16 1368 PInt32 *int32 1369 PInt64 *int64 1370 PUint *uint 1371 PUint8 *uint8 1372 PUint16 *uint16 1373 PUint32 *uint32 1374 PUint64 *uint64 1375 PUintptr *uintptr 1376 PFloat32 *float32 1377 PFloat64 *float64 1378 1379 String string 1380 PString *string 1381 1382 Map map[string]Small 1383 MapP map[string]*Small 1384 PMap *map[string]Small 1385 PMapP *map[string]*Small 1386 1387 EmptyMap map[string]Small 1388 NilMap map[string]Small 1389 1390 Slice []Small 1391 SliceP []*Small 1392 PSlice *[]Small 1393 PSliceP *[]*Small 1394 1395 EmptySlice []Small 1396 NilSlice []Small 1397 1398 StringSlice []string 1399 ByteSlice []byte 1400 1401 Small Small 1402 PSmall *Small 1403 PPSmall **Small 1404 1405 Interface any 1406 PInterface *any 1407 1408 unexported int //nolint:unused // it is used, but only via reflection // MODIFIED: added nolint annotation 1409 } 1410 1411 type Small struct { 1412 Tag string 1413 } 1414 1415 var allValue = All{ 1416 Bool: true, 1417 Int: 2, 1418 Int8: 3, 1419 Int16: 4, 1420 Int32: 5, 1421 Int64: 6, 1422 Uint: 7, 1423 Uint8: 8, 1424 Uint16: 9, 1425 Uint32: 10, 1426 Uint64: 11, 1427 Uintptr: 12, 1428 Float32: 14.1, 1429 Float64: 15.1, 1430 Foo: "foo", 1431 Foo2: "foo2", 1432 IntStr: 42, 1433 UintptrStr: 44, 1434 String: "16", 1435 Map: map[string]Small{ 1436 "17": {Tag: "tag17"}, 1437 "18": {Tag: "tag18"}, 1438 }, 1439 MapP: map[string]*Small{ 1440 "19": {Tag: "tag19"}, 1441 "20": nil, 1442 }, 1443 EmptyMap: map[string]Small{}, 1444 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, 1445 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, 1446 EmptySlice: []Small{}, 1447 StringSlice: []string{"str24", "str25", "str26"}, 1448 ByteSlice: []byte{27, 28, 29}, 1449 Small: Small{Tag: "tag30"}, 1450 PSmall: &Small{Tag: "tag31"}, 1451 Interface: 5.2, 1452 } 1453 1454 var pallValue = All{ 1455 PBool: &allValue.Bool, 1456 PInt: &allValue.Int, 1457 PInt8: &allValue.Int8, 1458 PInt16: &allValue.Int16, 1459 PInt32: &allValue.Int32, 1460 PInt64: &allValue.Int64, 1461 PUint: &allValue.Uint, 1462 PUint8: &allValue.Uint8, 1463 PUint16: &allValue.Uint16, 1464 PUint32: &allValue.Uint32, 1465 PUint64: &allValue.Uint64, 1466 PUintptr: &allValue.Uintptr, 1467 PFloat32: &allValue.Float32, 1468 PFloat64: &allValue.Float64, 1469 PString: &allValue.String, 1470 PMap: &allValue.Map, 1471 PMapP: &allValue.MapP, 1472 PSlice: &allValue.Slice, 1473 PSliceP: &allValue.SliceP, 1474 PPSmall: &allValue.PSmall, 1475 PInterface: &allValue.Interface, 1476 } 1477 1478 var allValueIndent = `{ 1479 "Bool": true, 1480 "Int": 2, 1481 "Int8": 3, 1482 "Int16": 4, 1483 "Int32": 5, 1484 "Int64": 6, 1485 "Uint": 7, 1486 "Uint8": 8, 1487 "Uint16": 9, 1488 "Uint32": 10, 1489 "Uint64": 11, 1490 "Uintptr": 12, 1491 "Float32": 14.1, 1492 "Float64": 15.1, 1493 "bar": "foo", 1494 "bar2": "foo2", 1495 "IntStr": "42", 1496 "UintptrStr": "44", 1497 "PBool": null, 1498 "PInt": null, 1499 "PInt8": null, 1500 "PInt16": null, 1501 "PInt32": null, 1502 "PInt64": null, 1503 "PUint": null, 1504 "PUint8": null, 1505 "PUint16": null, 1506 "PUint32": null, 1507 "PUint64": null, 1508 "PUintptr": null, 1509 "PFloat32": null, 1510 "PFloat64": null, 1511 "String": "16", 1512 "PString": null, 1513 "Map": { 1514 "17": { 1515 "Tag": "tag17" 1516 }, 1517 "18": { 1518 "Tag": "tag18" 1519 } 1520 }, 1521 "MapP": { 1522 "19": { 1523 "Tag": "tag19" 1524 }, 1525 "20": null 1526 }, 1527 "PMap": null, 1528 "PMapP": null, 1529 "EmptyMap": {}, 1530 "NilMap": null, 1531 "Slice": [ 1532 { 1533 "Tag": "tag20" 1534 }, 1535 { 1536 "Tag": "tag21" 1537 } 1538 ], 1539 "SliceP": [ 1540 { 1541 "Tag": "tag22" 1542 }, 1543 null, 1544 { 1545 "Tag": "tag23" 1546 } 1547 ], 1548 "PSlice": null, 1549 "PSliceP": null, 1550 "EmptySlice": [], 1551 "NilSlice": null, 1552 "StringSlice": [ 1553 "str24", 1554 "str25", 1555 "str26" 1556 ], 1557 "ByteSlice": "Gxwd", 1558 "Small": { 1559 "Tag": "tag30" 1560 }, 1561 "PSmall": { 1562 "Tag": "tag31" 1563 }, 1564 "PPSmall": null, 1565 "Interface": 5.2, 1566 "PInterface": null 1567 }` 1568 1569 var allValueCompact = strings.Map(noSpace, allValueIndent) 1570 1571 var pallValueIndent = `{ 1572 "Bool": false, 1573 "Int": 0, 1574 "Int8": 0, 1575 "Int16": 0, 1576 "Int32": 0, 1577 "Int64": 0, 1578 "Uint": 0, 1579 "Uint8": 0, 1580 "Uint16": 0, 1581 "Uint32": 0, 1582 "Uint64": 0, 1583 "Uintptr": 0, 1584 "Float32": 0, 1585 "Float64": 0, 1586 "bar": "", 1587 "bar2": "", 1588 "IntStr": "0", 1589 "UintptrStr": "0", 1590 "PBool": true, 1591 "PInt": 2, 1592 "PInt8": 3, 1593 "PInt16": 4, 1594 "PInt32": 5, 1595 "PInt64": 6, 1596 "PUint": 7, 1597 "PUint8": 8, 1598 "PUint16": 9, 1599 "PUint32": 10, 1600 "PUint64": 11, 1601 "PUintptr": 12, 1602 "PFloat32": 14.1, 1603 "PFloat64": 15.1, 1604 "String": "", 1605 "PString": "16", 1606 "Map": null, 1607 "MapP": null, 1608 "PMap": { 1609 "17": { 1610 "Tag": "tag17" 1611 }, 1612 "18": { 1613 "Tag": "tag18" 1614 } 1615 }, 1616 "PMapP": { 1617 "19": { 1618 "Tag": "tag19" 1619 }, 1620 "20": null 1621 }, 1622 "EmptyMap": null, 1623 "NilMap": null, 1624 "Slice": null, 1625 "SliceP": null, 1626 "PSlice": [ 1627 { 1628 "Tag": "tag20" 1629 }, 1630 { 1631 "Tag": "tag21" 1632 } 1633 ], 1634 "PSliceP": [ 1635 { 1636 "Tag": "tag22" 1637 }, 1638 null, 1639 { 1640 "Tag": "tag23" 1641 } 1642 ], 1643 "EmptySlice": null, 1644 "NilSlice": null, 1645 "StringSlice": null, 1646 "ByteSlice": null, 1647 "Small": { 1648 "Tag": "" 1649 }, 1650 "PSmall": null, 1651 "PPSmall": { 1652 "Tag": "tag31" 1653 }, 1654 "Interface": null, 1655 "PInterface": 5.2 1656 }` 1657 1658 var pallValueCompact = strings.Map(noSpace, pallValueIndent) 1659 1660 func TestRefUnmarshal(t *testing.T) { 1661 t.Parallel() // MODIFIED: added 1662 type S struct { 1663 // Ref is defined in encode_test.go. 1664 R0 Ref 1665 R1 *Ref 1666 R2 RefText 1667 R3 *RefText 1668 } 1669 want := S{ 1670 R0: 12, 1671 R1: new(Ref), 1672 R2: 13, 1673 R3: new(RefText), 1674 } 1675 *want.R1 = 12 1676 *want.R3 = 13 1677 1678 var got S 1679 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil { 1680 t.Fatalf("Unmarshal: %v", err) 1681 } 1682 if !reflect.DeepEqual(got, want) { 1683 t.Errorf("got %+v, want %+v", got, want) 1684 } 1685 } 1686 1687 // Test that the empty string doesn't panic decoding when ,string is specified 1688 // Issue 3450 1689 func TestEmptyString(t *testing.T) { 1690 t.Parallel() // MODIFIED: added 1691 type T2 struct { 1692 Number1 int `json:",string"` 1693 Number2 int `json:",string"` 1694 } 1695 data := `{"Number1":"1", "Number2":""}` 1696 dec := NewDecoder(strings.NewReader(data)) 1697 var t2 T2 1698 err := dec.Decode(&t2) 1699 if err == nil { 1700 t.Fatal("Decode: did not return error") 1701 } 1702 if t2.Number1 != 1 { 1703 t.Fatal("Decode: did not set Number1") 1704 } 1705 } 1706 1707 // Test that a null for ,string is not replaced with the previous quoted string (issue 7046). 1708 // It should also not be an error (issue 2540, issue 8587). 1709 func TestNullString(t *testing.T) { 1710 t.Parallel() // MODIFIED: added 1711 type T struct { 1712 A int `json:",string"` 1713 B int `json:",string"` 1714 C *int `json:",string"` 1715 } 1716 data := []byte(`{"A": "1", "B": null, "C": null}`) 1717 var s T 1718 s.B = 1 1719 s.C = new(int) 1720 *s.C = 2 1721 err := Unmarshal(data, &s) 1722 if err != nil { 1723 t.Fatalf("Unmarshal: %v", err) 1724 } 1725 if s.B != 1 || s.C != nil { 1726 t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C) 1727 } 1728 } 1729 1730 func intp(x int) *int { 1731 p := new(int) 1732 *p = x 1733 return p 1734 } 1735 1736 func intpp(x *int) **int { 1737 pp := new(*int) 1738 *pp = x 1739 return pp 1740 } 1741 1742 var interfaceSetTests = []struct { 1743 pre any 1744 json string 1745 post any 1746 }{ 1747 {"foo", `"bar"`, "bar"}, 1748 {"foo", `2`, 2.0}, 1749 {"foo", `true`, true}, 1750 {"foo", `null`, nil}, 1751 1752 {nil, `null`, nil}, 1753 {new(int), `null`, nil}, 1754 {(*int)(nil), `null`, nil}, 1755 {new(*int), `null`, new(*int)}, 1756 {(**int)(nil), `null`, nil}, 1757 {intp(1), `null`, nil}, 1758 {intpp(nil), `null`, intpp(nil)}, 1759 {intpp(intp(1)), `null`, intpp(nil)}, 1760 } 1761 1762 func TestInterfaceSet(t *testing.T) { 1763 t.Parallel() // MODIFIED: added 1764 for _, tt := range interfaceSetTests { 1765 b := struct{ X any }{tt.pre} 1766 blob := `{"X":` + tt.json + `}` 1767 if err := Unmarshal([]byte(blob), &b); err != nil { 1768 t.Errorf("Unmarshal %#q: %v", blob, err) 1769 continue 1770 } 1771 if !reflect.DeepEqual(b.X, tt.post) { 1772 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post) 1773 } 1774 } 1775 } 1776 1777 type NullTest struct { 1778 Bool bool 1779 Int int 1780 Int8 int8 1781 Int16 int16 1782 Int32 int32 1783 Int64 int64 1784 Uint uint 1785 Uint8 uint8 1786 Uint16 uint16 1787 Uint32 uint32 1788 Uint64 uint64 1789 Float32 float32 1790 Float64 float64 1791 String string 1792 PBool *bool 1793 Map map[string]string 1794 Slice []string 1795 Interface any 1796 1797 PRaw *RawMessage 1798 PTime *time.Time 1799 PBigInt *big.Int 1800 PText *MustNotUnmarshalText 1801 PBuffer *bytes.Buffer // has methods, just not relevant ones 1802 PStruct *struct{} 1803 1804 Raw RawMessage 1805 Time time.Time 1806 BigInt big.Int 1807 Text MustNotUnmarshalText 1808 Buffer bytes.Buffer 1809 Struct struct{} 1810 } 1811 1812 // JSON null values should be ignored for primitives and string values instead of resulting in an error. 1813 // Issue 2540 1814 func TestUnmarshalNulls(t *testing.T) { 1815 t.Parallel() // MODIFIED: added 1816 // Unmarshal docs: 1817 // The JSON null value unmarshals into an interface, map, pointer, or slice 1818 // by setting that Go value to nil. Because null is often used in JSON to mean 1819 // ``not present,'' unmarshaling a JSON null into any other Go type has no effect 1820 // on the value and produces no error. 1821 1822 jsonData := []byte(`{ 1823 "Bool" : null, 1824 "Int" : null, 1825 "Int8" : null, 1826 "Int16" : null, 1827 "Int32" : null, 1828 "Int64" : null, 1829 "Uint" : null, 1830 "Uint8" : null, 1831 "Uint16" : null, 1832 "Uint32" : null, 1833 "Uint64" : null, 1834 "Float32" : null, 1835 "Float64" : null, 1836 "String" : null, 1837 "PBool": null, 1838 "Map": null, 1839 "Slice": null, 1840 "Interface": null, 1841 "PRaw": null, 1842 "PTime": null, 1843 "PBigInt": null, 1844 "PText": null, 1845 "PBuffer": null, 1846 "PStruct": null, 1847 "Raw": null, 1848 "Time": null, 1849 "BigInt": null, 1850 "Text": null, 1851 "Buffer": null, 1852 "Struct": null 1853 }`) 1854 nulls := NullTest{ 1855 Bool: true, 1856 Int: 2, 1857 Int8: 3, 1858 Int16: 4, 1859 Int32: 5, 1860 Int64: 6, 1861 Uint: 7, 1862 Uint8: 8, 1863 Uint16: 9, 1864 Uint32: 10, 1865 Uint64: 11, 1866 Float32: 12.1, 1867 Float64: 13.1, 1868 String: "14", 1869 PBool: new(bool), 1870 Map: map[string]string{}, 1871 Slice: []string{}, 1872 Interface: new(MustNotUnmarshalJSON), 1873 PRaw: new(RawMessage), 1874 PTime: new(time.Time), 1875 PBigInt: new(big.Int), 1876 PText: new(MustNotUnmarshalText), 1877 PStruct: new(struct{}), 1878 PBuffer: new(bytes.Buffer), 1879 Raw: RawMessage("123"), 1880 Time: time.Unix(123456789, 0), 1881 BigInt: *big.NewInt(123), 1882 } 1883 1884 before := nulls.Time.String() 1885 1886 err := Unmarshal(jsonData, &nulls) 1887 if err != nil { 1888 t.Errorf("Unmarshal of null values failed: %v", err) 1889 } 1890 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 || 1891 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 || 1892 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" { 1893 t.Errorf("Unmarshal of null values affected primitives") 1894 } 1895 1896 if nulls.PBool != nil { 1897 t.Errorf("Unmarshal of null did not clear nulls.PBool") 1898 } 1899 if nulls.Map != nil { 1900 t.Errorf("Unmarshal of null did not clear nulls.Map") 1901 } 1902 if nulls.Slice != nil { 1903 t.Errorf("Unmarshal of null did not clear nulls.Slice") 1904 } 1905 if nulls.Interface != nil { 1906 t.Errorf("Unmarshal of null did not clear nulls.Interface") 1907 } 1908 if nulls.PRaw != nil { 1909 t.Errorf("Unmarshal of null did not clear nulls.PRaw") 1910 } 1911 if nulls.PTime != nil { 1912 t.Errorf("Unmarshal of null did not clear nulls.PTime") 1913 } 1914 if nulls.PBigInt != nil { 1915 t.Errorf("Unmarshal of null did not clear nulls.PBigInt") 1916 } 1917 if nulls.PText != nil { 1918 t.Errorf("Unmarshal of null did not clear nulls.PText") 1919 } 1920 if nulls.PBuffer != nil { 1921 t.Errorf("Unmarshal of null did not clear nulls.PBuffer") 1922 } 1923 if nulls.PStruct != nil { 1924 t.Errorf("Unmarshal of null did not clear nulls.PStruct") 1925 } 1926 1927 if string(nulls.Raw) != "null" { 1928 t.Errorf("Unmarshal of RawMessage null did not record null: %v", string(nulls.Raw)) 1929 } 1930 if nulls.Time.String() != before { 1931 t.Errorf("Unmarshal of time.Time null set time to %v", nulls.Time.String()) 1932 } 1933 if nulls.BigInt.String() != "123" { 1934 t.Errorf("Unmarshal of big.Int null set int to %v", nulls.BigInt.String()) 1935 } 1936 } 1937 1938 type MustNotUnmarshalJSON struct{} 1939 1940 func (x MustNotUnmarshalJSON) UnmarshalJSON(data []byte) error { 1941 return errors.New("MustNotUnmarshalJSON was used") 1942 } 1943 1944 type MustNotUnmarshalText struct{} 1945 1946 func (x MustNotUnmarshalText) UnmarshalText(text []byte) error { 1947 return errors.New("MustNotUnmarshalText was used") 1948 } 1949 1950 func TestStringKind(t *testing.T) { 1951 t.Parallel() // MODIFIED: added 1952 type stringKind string 1953 1954 var m1, m2 map[stringKind]int 1955 m1 = map[stringKind]int{ 1956 "foo": 42, 1957 } 1958 1959 data, err := Marshal(m1) 1960 if err != nil { 1961 t.Errorf("Unexpected error marshaling: %v", err) 1962 } 1963 1964 err = Unmarshal(data, &m2) 1965 if err != nil { 1966 t.Errorf("Unexpected error unmarshaling: %v", err) 1967 } 1968 1969 if !reflect.DeepEqual(m1, m2) { 1970 t.Error("Items should be equal after encoding and then decoding") 1971 } 1972 } 1973 1974 // Custom types with []byte as underlying type could not be marshaled 1975 // and then unmarshaled. 1976 // Issue 8962. 1977 func TestByteKind(t *testing.T) { 1978 t.Parallel() // MODIFIED: added 1979 type byteKind []byte 1980 1981 a := byteKind("hello") 1982 1983 data, err := Marshal(a) 1984 if err != nil { 1985 t.Error(err) 1986 } 1987 if !reflect.DeepEqual(data, []byte(`"aGVsbG8="`)) { // MODIFIED: added 1988 t.Errorf("expected %q == %q", data, `"aGVsbG8="`) // MODIFIED: added 1989 } // MODIFIED: added 1990 var b byteKind 1991 err = Unmarshal(data, &b) 1992 if err != nil { 1993 t.Fatal(err) 1994 } 1995 if !reflect.DeepEqual(a, b) { 1996 t.Errorf("expected %v == %v", a, b) 1997 } 1998 } 1999 2000 // The fix for issue 8962 introduced a regression. 2001 // Issue 12921. 2002 func TestSliceOfCustomByte(t *testing.T) { 2003 t.Parallel() // MODIFIED: added 2004 type Uint8 uint8 2005 2006 a := []Uint8("hello") 2007 2008 data, err := Marshal(a) 2009 if err != nil { 2010 t.Fatal(err) 2011 } 2012 if !reflect.DeepEqual(data, []byte(`"aGVsbG8="`)) { // MODIFIED: added 2013 t.Errorf("expected %q == %q", data, `"aGVsbG8="`) // MODIFIED: added 2014 } // MODIFIED: added 2015 var b []Uint8 2016 err = Unmarshal(data, &b) 2017 if err != nil { 2018 t.Fatal(err) 2019 } 2020 if !reflect.DeepEqual(a, b) { 2021 t.Fatalf("expected %v == %v", a, b) 2022 } 2023 } 2024 2025 var decodeTypeErrorTests = []struct { 2026 dest any 2027 src string 2028 }{ 2029 {new(string), `{"user": "name"}`}, // issue 4628. 2030 {new(error), `{}`}, // issue 4222 2031 {new(error), `[]`}, 2032 {new(error), `""`}, 2033 {new(error), `123`}, 2034 {new(error), `true`}, 2035 } 2036 2037 func TestUnmarshalTypeError(t *testing.T) { 2038 t.Parallel() // MODIFIED: added 2039 for _, item := range decodeTypeErrorTests { 2040 err := Unmarshal([]byte(item.src), item.dest) 2041 if _, ok := err.(*UnmarshalTypeError); !ok { 2042 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", 2043 item.src, item.dest, err) 2044 } 2045 } 2046 } 2047 2048 var unmarshalSyntaxTests = []string{ 2049 "tru", 2050 "fals", 2051 "nul", 2052 "123e", 2053 `"hello`, 2054 `[1,2,3`, 2055 `{"key":1`, 2056 `{"key":1,`, 2057 } 2058 2059 func TestUnmarshalSyntax(t *testing.T) { 2060 t.Parallel() // MODIFIED: added 2061 var x any 2062 for _, src := range unmarshalSyntaxTests { 2063 err := Unmarshal([]byte(src), &x) 2064 if _, ok := err.(*SyntaxError); !ok { 2065 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) 2066 } 2067 } 2068 } 2069 2070 // Test handling of unexported fields that should be ignored. 2071 // Issue 4660 2072 type unexportedFields struct { 2073 Name string 2074 m map[string]any `json:"-"` //nolint:unused,govet // testing handling of unused fields // MODIFIED: added nolint annotation 2075 m2 map[string]any `json:"abcd"` //nolint:unused // testing handling of unused fields // MODIFIED: added nolint annotation 2076 2077 s []int `json:"-"` //nolint:unused // testing handling of unused fields // MODIFIED: added nolint annotation 2078 } 2079 2080 func TestUnmarshalUnexported(t *testing.T) { 2081 t.Parallel() // MODIFIED: added 2082 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}, "s": [2, 3]}` 2083 want := &unexportedFields{Name: "Bob"} 2084 2085 out := &unexportedFields{} 2086 err := Unmarshal([]byte(input), out) 2087 if err != nil { 2088 t.Errorf("got error %v, expected nil", err) 2089 } 2090 if !reflect.DeepEqual(out, want) { 2091 t.Errorf("got %q, want %q", out, want) 2092 } 2093 } 2094 2095 // Time3339 is a time.Time which encodes to and from JSON 2096 // as an RFC 3339 time in UTC. 2097 type Time3339 time.Time 2098 2099 func (t *Time3339) UnmarshalJSON(b []byte) error { 2100 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { 2101 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) 2102 } 2103 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) 2104 if err != nil { 2105 return err 2106 } 2107 *t = Time3339(tm) 2108 return nil 2109 } 2110 2111 func TestUnmarshalJSONLiteralError(t *testing.T) { 2112 t.Parallel() // MODIFIED: added 2113 var t3 Time3339 2114 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) 2115 if err == nil { 2116 t.Fatalf("expected error; got time %v", time.Time(t3)) 2117 } 2118 if !strings.Contains(err.Error(), "range") { 2119 t.Errorf("got err = %v; want out of range error", err) 2120 } 2121 } 2122 2123 // Test that extra object elements in an array do not result in a 2124 // "data changing underfoot" error. 2125 // Issue 3717 2126 func TestSkipArrayObjects(t *testing.T) { 2127 t.Parallel() // MODIFIED: added 2128 json := `[{}]` 2129 var dest [0]any 2130 2131 err := Unmarshal([]byte(json), &dest) 2132 if err != nil { 2133 t.Errorf("got error %q, want nil", err) 2134 } 2135 } 2136 2137 // Test semantics of pre-filled data, such as struct fields, map elements, 2138 // slices, and arrays. 2139 // Issues 4900 and 8837, among others. 2140 func TestPrefilled(t *testing.T) { 2141 t.Parallel() // MODIFIED: added 2142 // Values here change, cannot reuse table across runs. 2143 var prefillTests = []struct { 2144 in string 2145 ptr any 2146 out any 2147 }{ 2148 { 2149 in: `{"X": 1, "Y": 2}`, 2150 ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5}, 2151 out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5}, 2152 }, 2153 { 2154 in: `{"X": 1, "Y": 2}`, 2155 ptr: &map[string]any{"X": float32(3), "Y": int16(4), "Z": 1.5}, 2156 out: &map[string]any{"X": float64(1), "Y": float64(2), "Z": 1.5}, 2157 }, 2158 { 2159 in: `[2]`, 2160 ptr: &[]int{1}, 2161 out: &[]int{2}, 2162 }, 2163 { 2164 in: `[2, 3]`, 2165 ptr: &[]int{1}, 2166 out: &[]int{2, 3}, 2167 }, 2168 { 2169 in: `[2, 3]`, 2170 ptr: &[...]int{1}, 2171 out: &[...]int{2}, 2172 }, 2173 { 2174 in: `[3]`, 2175 ptr: &[...]int{1, 2}, 2176 out: &[...]int{3, 0}, 2177 }, 2178 } 2179 2180 for _, tt := range prefillTests { 2181 ptrstr := fmt.Sprintf("%v", tt.ptr) 2182 err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here 2183 if err != nil { 2184 t.Errorf("Unmarshal: %v", err) 2185 } 2186 if !reflect.DeepEqual(tt.ptr, tt.out) { 2187 t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out) 2188 } 2189 } 2190 } 2191 2192 var invalidUnmarshalTests = []struct { 2193 v any 2194 want string 2195 }{ 2196 {nil, "json: Unmarshal(nil)"}, 2197 {struct{}{}, "json: Unmarshal(non-pointer struct {})"}, 2198 {(*int)(nil), "json: Unmarshal(nil *int)"}, 2199 } 2200 2201 func TestInvalidUnmarshal(t *testing.T) { 2202 t.Parallel() // MODIFIED: added 2203 buf := []byte(`{"a":"1"}`) 2204 for _, tt := range invalidUnmarshalTests { 2205 err := Unmarshal(buf, tt.v) 2206 if err == nil { 2207 t.Errorf("Unmarshal expecting error, got nil") 2208 continue 2209 } 2210 if got := err.Error(); got != tt.want { 2211 t.Errorf("Unmarshal = %q; want %q", got, tt.want) 2212 } 2213 } 2214 } 2215 2216 var invalidUnmarshalTextTests = []struct { 2217 v any 2218 want string 2219 }{ 2220 {nil, "json: Unmarshal(nil)"}, 2221 {struct{}{}, "json: Unmarshal(non-pointer struct {})"}, 2222 {(*int)(nil), "json: Unmarshal(nil *int)"}, 2223 {new(net.IP), "json: cannot unmarshal number into Go value of type *net.IP"}, 2224 } 2225 2226 func TestInvalidUnmarshalText(t *testing.T) { 2227 t.Parallel() // MODIFIED: added 2228 buf := []byte(`123`) 2229 for _, tt := range invalidUnmarshalTextTests { 2230 err := Unmarshal(buf, tt.v) 2231 if err == nil { 2232 t.Errorf("Unmarshal expecting error, got nil") 2233 continue 2234 } 2235 if got := err.Error(); got != tt.want { 2236 t.Errorf("Unmarshal = %q; want %q", got, tt.want) 2237 } 2238 } 2239 } 2240 2241 // Test that string option is ignored for invalid types. 2242 // Issue 9812. 2243 func TestInvalidStringOption(t *testing.T) { 2244 t.Parallel() // MODIFIED: added 2245 num := 0 2246 item := struct { 2247 T time.Time `json:",string"` //nolint:staticcheck // testing handling of bad options // MODIFIED: added nolint annotation 2248 M map[string]string `json:",string"` //nolint:staticcheck // testing handling of bad options // MODIFIED: added nolint annotation 2249 S []string `json:",string"` //nolint:staticcheck // testing handling of bad options // MODIFIED: added nolint annotation 2250 A [1]string `json:",string"` //nolint:staticcheck // testing handling of bad options // MODIFIED: added nolint annotation 2251 I any `json:",string"` //nolint:staticcheck // testing handling of bad options // MODIFIED: added nolint annotation 2252 P *int `json:",string"` 2253 }{M: make(map[string]string), S: make([]string, 0), I: num, P: &num} 2254 2255 data, err := Marshal(item) 2256 if err != nil { 2257 t.Fatalf("Marshal: %v", err) 2258 } 2259 2260 err = Unmarshal(data, &item) 2261 if err != nil { 2262 t.Fatalf("Unmarshal: %v", err) 2263 } 2264 } 2265 2266 // Test unmarshal behavior with regards to embedded unexported structs. 2267 // 2268 // (Issue 21357) If the embedded struct is a pointer and is unallocated, 2269 // this returns an error because unmarshal cannot set the field. 2270 // 2271 // (Issue 24152) If the embedded struct is given an explicit name, 2272 // ensure that the normal unmarshal logic does not panic in reflect. 2273 // 2274 // (Issue 28145) If the embedded struct is given an explicit name and has 2275 // exported methods, don't cause a panic trying to get its value. 2276 func TestUnmarshalEmbeddedUnexported(t *testing.T) { 2277 t.Parallel() // MODIFIED: added 2278 type ( 2279 embed1 struct{ Q int } 2280 embed2 struct{ Q int } 2281 embed3 struct { 2282 Q int64 `json:",string"` 2283 } 2284 S1 struct { 2285 *embed1 2286 R int 2287 } 2288 S2 struct { 2289 *embed1 2290 Q int 2291 } 2292 S3 struct { 2293 embed1 2294 R int 2295 } 2296 S4 struct { 2297 *embed1 2298 embed2 2299 } 2300 S5 struct { 2301 *embed3 2302 R int 2303 } 2304 S6 struct { 2305 embed1 `json:"embed1"` 2306 } 2307 S7 struct { 2308 embed1 `json:"embed1"` 2309 embed2 2310 } 2311 S8 struct { 2312 embed1 `json:"embed1"` 2313 embed2 `json:"embed2"` 2314 Q int 2315 } 2316 S9 struct { 2317 unexportedWithMethods `json:"embed"` 2318 } 2319 ) 2320 2321 tests := []struct { 2322 in string 2323 ptr any 2324 out any 2325 err error 2326 }{{ 2327 // Error since we cannot set S1.embed1, but still able to set S1.R. 2328 in: `{"R":2,"Q":1}`, 2329 ptr: new(S1), 2330 out: &S1{R: 2}, 2331 err: fmt.Errorf("json: cannot set embedded pointer to unexported struct: json.embed1"), 2332 }, { 2333 // The top level Q field takes precedence. 2334 in: `{"Q":1}`, 2335 ptr: new(S2), 2336 out: &S2{Q: 1}, 2337 }, { 2338 // No issue with non-pointer variant. 2339 in: `{"R":2,"Q":1}`, 2340 ptr: new(S3), 2341 out: &S3{embed1: embed1{Q: 1}, R: 2}, 2342 }, { 2343 // No error since both embedded structs have field R, which annihilate each other. 2344 // Thus, no attempt is made at setting S4.embed1. 2345 in: `{"R":2}`, 2346 ptr: new(S4), 2347 out: new(S4), 2348 }, { 2349 // Error since we cannot set S5.embed1, but still able to set S5.R. 2350 in: `{"R":2,"Q":1}`, 2351 ptr: new(S5), 2352 out: &S5{R: 2}, 2353 err: fmt.Errorf("json: cannot set embedded pointer to unexported struct: json.embed3"), 2354 }, { 2355 // Issue 24152, ensure decodeState.indirect does not panic. 2356 in: `{"embed1": {"Q": 1}}`, 2357 ptr: new(S6), 2358 out: &S6{embed1{1}}, 2359 }, { 2360 // Issue 24153, check that we can still set forwarded fields even in 2361 // the presence of a name conflict. 2362 // 2363 // This relies on obscure behavior of reflect where it is possible 2364 // to set a forwarded exported field on an unexported embedded struct 2365 // even though there is a name conflict, even when it would have been 2366 // impossible to do so according to Go visibility rules. 2367 // Go forbids this because it is ambiguous whether S7.Q refers to 2368 // S7.embed1.Q or S7.embed2.Q. Since embed1 and embed2 are unexported, 2369 // it should be impossible for an external package to set either Q. 2370 // 2371 // It is probably okay for a future reflect change to break this. 2372 in: `{"embed1": {"Q": 1}, "Q": 2}`, 2373 ptr: new(S7), 2374 out: &S7{embed1{1}, embed2{2}}, 2375 }, { 2376 // Issue 24153, similar to the S7 case. 2377 in: `{"embed1": {"Q": 1}, "embed2": {"Q": 2}, "Q": 3}`, 2378 ptr: new(S8), 2379 out: &S8{embed1{1}, embed2{2}, 3}, 2380 }, { 2381 // Issue 228145, similar to the cases above. 2382 in: `{"embed": {}}`, 2383 ptr: new(S9), 2384 out: &S9{}, 2385 }} 2386 2387 for i, tt := range tests { 2388 err := Unmarshal([]byte(tt.in), tt.ptr) 2389 if !equalError(err, tt.err) { 2390 t.Errorf("#%d: %v, want %v", i, err, tt.err) 2391 } 2392 if !reflect.DeepEqual(tt.ptr, tt.out) { 2393 t.Errorf("#%d: mismatch\ngot: %#+v\nwant: %#+v", i, tt.ptr, tt.out) 2394 } 2395 } 2396 } 2397 2398 func TestUnmarshalErrorAfterMultipleJSON(t *testing.T) { 2399 t.Parallel() // MODIFIED: added 2400 tests := []struct { 2401 in string 2402 err error 2403 }{{ 2404 in: `1 false null :`, 2405 err: &SyntaxError{"invalid character ':' looking for beginning of value", 14}, 2406 }, { 2407 in: `1 [] [,]`, 2408 err: &SyntaxError{"invalid character ',' looking for beginning of value", 7}, 2409 }, { 2410 in: `1 [] [true:]`, 2411 err: &SyntaxError{"invalid character ':' after array element", 11}, 2412 }, { 2413 in: `1 {} {"x"=}`, 2414 err: &SyntaxError{"invalid character '=' after object key", 14}, 2415 }, { 2416 in: `falsetruenul#`, 2417 err: &SyntaxError{"invalid character '#' in literal null (expecting 'l')", 13}, 2418 }} 2419 for i, tt := range tests { 2420 dec := NewDecoder(strings.NewReader(tt.in)) 2421 var err error 2422 for { 2423 var v any 2424 if err = dec.Decode(&v); err != nil { 2425 break 2426 } 2427 } 2428 if !reflect.DeepEqual(err, tt.err) { 2429 t.Errorf("#%d: got %#v, want %#v", i, err, tt.err) 2430 } 2431 } 2432 } 2433 2434 type unmarshalPanic struct{} 2435 2436 func (unmarshalPanic) UnmarshalJSON([]byte) error { panic(0xdead) } 2437 2438 func TestUnmarshalPanic(t *testing.T) { 2439 t.Parallel() // MODIFIED: added 2440 defer func() { 2441 if got := recover(); !reflect.DeepEqual(got, 0xdead) { 2442 t.Errorf("panic() = (%T)(%v), want 0xdead", got, got) 2443 } 2444 }() 2445 _ = Unmarshal([]byte("{}"), &unmarshalPanic{}) // MODIFIED: added the _ dogsled for the linter 2446 t.Fatalf("Unmarshal should have panicked") 2447 } 2448 2449 // The decoder used to hang if decoding into an interface pointing to its own address. 2450 // See golang.org/issues/31740. 2451 func TestUnmarshalRecursivePointer(t *testing.T) { 2452 t.Parallel() // MODIFIED: added 2453 var v any 2454 v = &v 2455 data := []byte(`{"a": "b"}`) 2456 2457 if err := Unmarshal(data, v); err != nil { 2458 t.Fatal(err) 2459 } 2460 } 2461 2462 type textUnmarshalerString string 2463 2464 func (m *textUnmarshalerString) UnmarshalText(text []byte) error { 2465 *m = textUnmarshalerString(strings.ToLower(string(text))) 2466 return nil 2467 } 2468 2469 // Test unmarshal to a map, where the map key is a user defined type. 2470 // See golang.org/issues/34437. 2471 func TestUnmarshalMapWithTextUnmarshalerStringKey(t *testing.T) { 2472 t.Parallel() // MODIFIED: added 2473 var p map[textUnmarshalerString]string 2474 if err := Unmarshal([]byte(`{"FOO": "1"}`), &p); err != nil { 2475 t.Fatalf("Unmarshal unexpected error: %v", err) 2476 } 2477 2478 if _, ok := p["foo"]; !ok { 2479 t.Errorf(`Key "foo" does not exist in map: %v`, p) 2480 } 2481 } 2482 2483 func TestUnmarshalRescanLiteralMangledUnquote(t *testing.T) { 2484 t.Parallel() // MODIFIED: added 2485 // See golang.org/issues/38105. 2486 var p map[textUnmarshalerString]string 2487 if err := Unmarshal([]byte(`{"开源":"12345开源"}`), &p); err != nil { 2488 t.Fatalf("Unmarshal unexpected error: %v", err) 2489 } 2490 if _, ok := p["开源"]; !ok { 2491 t.Errorf(`Key "开源" does not exist in map: %v`, p) 2492 } 2493 2494 // See golang.org/issues/38126. 2495 type T struct { 2496 F1 string `json:"F1,string"` 2497 } 2498 t1 := T{"aaa\tbbb"} 2499 2500 b, err := Marshal(t1) 2501 if err != nil { 2502 t.Fatalf("Marshal unexpected error: %v", err) 2503 } 2504 var t2 T 2505 if err := Unmarshal(b, &t2); err != nil { 2506 t.Fatalf("Unmarshal unexpected error: %v", err) 2507 } 2508 if t1 != t2 { 2509 t.Errorf("Marshal and Unmarshal roundtrip mismatch: want %q got %q", t1, t2) 2510 } 2511 2512 // See golang.org/issues/39555. 2513 input := map[textUnmarshalerString]string{"FOO": "", `"`: ""} 2514 2515 encoded, err := Marshal(input) 2516 if err != nil { 2517 t.Fatalf("Marshal unexpected error: %v", err) 2518 } 2519 var got map[textUnmarshalerString]string 2520 if err := Unmarshal(encoded, &got); err != nil { 2521 t.Fatalf("Unmarshal unexpected error: %v", err) 2522 } 2523 want := map[textUnmarshalerString]string{"foo": "", `"`: ""} 2524 if !reflect.DeepEqual(want, got) { 2525 t.Fatalf("Unexpected roundtrip result:\nwant: %q\ngot: %q", want, got) 2526 } 2527 } 2528 2529 func TestUnmarshalMaxDepth(t *testing.T) { 2530 t.Parallel() // MODIFIED: added 2531 testcases := []struct { 2532 name string 2533 data string 2534 errMaxDepth bool 2535 }{ 2536 { 2537 name: "ArrayUnderMaxNestingDepth", 2538 data: `{"a":` + strings.Repeat(`[`, 10000-1) + strings.Repeat(`]`, 10000-1) + `}`, 2539 errMaxDepth: false, 2540 }, 2541 { 2542 name: "ArrayOverMaxNestingDepth", 2543 data: `{"a":` + strings.Repeat(`[`, 10000) + strings.Repeat(`]`, 10000) + `}`, 2544 errMaxDepth: true, 2545 }, 2546 { 2547 name: "ArrayOverStackDepth", 2548 data: `{"a":` + strings.Repeat(`[`, 3000000) + strings.Repeat(`]`, 3000000) + `}`, 2549 errMaxDepth: true, 2550 }, 2551 { 2552 name: "ObjectUnderMaxNestingDepth", 2553 data: `{"a":` + strings.Repeat(`{"a":`, 10000-1) + `0` + strings.Repeat(`}`, 10000-1) + `}`, 2554 errMaxDepth: false, 2555 }, 2556 { 2557 name: "ObjectOverMaxNestingDepth", 2558 data: `{"a":` + strings.Repeat(`{"a":`, 10000) + `0` + strings.Repeat(`}`, 10000) + `}`, 2559 errMaxDepth: true, 2560 }, 2561 { 2562 name: "ObjectOverStackDepth", 2563 data: `{"a":` + strings.Repeat(`{"a":`, 3000000) + `0` + strings.Repeat(`}`, 3000000) + `}`, 2564 errMaxDepth: true, 2565 }, 2566 } 2567 2568 targets := []struct { 2569 name string 2570 newValue func() any 2571 }{ 2572 { 2573 name: "unstructured", 2574 newValue: func() any { 2575 var v any 2576 return &v 2577 }, 2578 }, 2579 { 2580 name: "typed named field", 2581 newValue: func() any { 2582 v := struct { 2583 A any `json:"a"` 2584 }{} 2585 return &v 2586 }, 2587 }, 2588 { 2589 name: "typed missing field", 2590 newValue: func() any { 2591 v := struct { 2592 B any `json:"b"` 2593 }{} 2594 return &v 2595 }, 2596 }, 2597 { 2598 name: "custom unmarshaler", 2599 newValue: func() any { 2600 v := unmarshaler{} 2601 return &v 2602 }, 2603 }, 2604 } 2605 2606 for _, tc := range testcases { 2607 tc := tc // MODIFIED: added 2608 for _, target := range targets { 2609 target := target // MODIFIED: added 2610 t.Run(target.name+"-"+tc.name, func(t *testing.T) { 2611 t.Parallel() // MODIFIED: added 2612 err := Unmarshal([]byte(tc.data), target.newValue()) 2613 if !tc.errMaxDepth { 2614 if err != nil { 2615 t.Errorf("unexpected error: %v", err) 2616 } 2617 } else { 2618 if err == nil { 2619 t.Errorf("expected error containing 'exceeded max depth', got none") 2620 } else if !strings.Contains(err.Error(), "exceeded max depth") { 2621 t.Errorf("expected error containing 'exceeded max depth', got: %v", err) 2622 } 2623 } 2624 }) 2625 } 2626 } 2627 }