Source file src/encoding/json/v2_decode_test.go

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

View as plain text