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