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

View as plain text