Source file src/encoding/json/decode_test.go

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

View as plain text