Source file src/encoding/json/v2_decode_test.go

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

View as plain text