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

View as plain text