Source file src/encoding/json/v2_encode_test.go

     1  // Copyright 2011 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  	"fmt"
    13  	"log"
    14  	"math"
    15  	"reflect"
    16  	"regexp"
    17  	"runtime/debug"
    18  	"strconv"
    19  	"testing"
    20  	"time"
    21  )
    22  
    23  type OptionalsEmpty struct {
    24  	Sr string `json:"sr"`
    25  	So string `json:"so,omitempty"`
    26  	Sw string `json:"-"`
    27  
    28  	Ir int `json:"omitempty"` // actually named omitempty, not an option
    29  	Io int `json:"io,omitempty"`
    30  
    31  	Slr []string `json:"slr,random"`
    32  	Slo []string `json:"slo,omitempty"`
    33  
    34  	Mr map[string]any `json:"mr"`
    35  	Mo map[string]any `json:",omitempty"`
    36  
    37  	Fr float64 `json:"fr"`
    38  	Fo float64 `json:"fo,omitempty"`
    39  
    40  	Br bool `json:"br"`
    41  	Bo bool `json:"bo,omitempty"`
    42  
    43  	Ur uint `json:"ur"`
    44  	Uo uint `json:"uo,omitempty"`
    45  
    46  	Str struct{} `json:"str"`
    47  	Sto struct{} `json:"sto,omitempty"`
    48  }
    49  
    50  func TestOmitEmpty(t *testing.T) {
    51  	const want = `{
    52   "sr": "",
    53   "omitempty": 0,
    54   "slr": null,
    55   "mr": {},
    56   "fr": 0,
    57   "br": false,
    58   "ur": 0,
    59   "str": {},
    60   "sto": {}
    61  }`
    62  	var o OptionalsEmpty
    63  	o.Sw = "something"
    64  	o.Mr = map[string]any{}
    65  	o.Mo = map[string]any{}
    66  
    67  	got, err := MarshalIndent(&o, "", " ")
    68  	if err != nil {
    69  		t.Fatalf("MarshalIndent error: %v", err)
    70  	}
    71  	if got := string(got); got != want {
    72  		t.Errorf("MarshalIndent:\n\tgot:  %s\n\twant: %s\n", indentNewlines(got), indentNewlines(want))
    73  	}
    74  }
    75  
    76  type NonZeroStruct struct{}
    77  
    78  func (nzs NonZeroStruct) IsZero() bool {
    79  	return false
    80  }
    81  
    82  type NoPanicStruct struct {
    83  	Int int `json:"int,omitzero"`
    84  }
    85  
    86  func (nps *NoPanicStruct) IsZero() bool {
    87  	return nps.Int != 0
    88  }
    89  
    90  type isZeroer interface {
    91  	IsZero() bool
    92  }
    93  
    94  type OptionalsZero struct {
    95  	Sr string `json:"sr"`
    96  	So string `json:"so,omitzero"`
    97  	Sw string `json:"-"`
    98  
    99  	Ir int `json:"omitzero"` // actually named omitzero, not an option
   100  	Io int `json:"io,omitzero"`
   101  
   102  	Slr       []string `json:"slr,random"`
   103  	Slo       []string `json:"slo,omitzero"`
   104  	SloNonNil []string `json:"slononnil,omitzero"`
   105  
   106  	Mr  map[string]any `json:"mr"`
   107  	Mo  map[string]any `json:",omitzero"`
   108  	Moo map[string]any `json:"moo,omitzero"`
   109  
   110  	Fr   float64    `json:"fr"`
   111  	Fo   float64    `json:"fo,omitzero"`
   112  	Foo  float64    `json:"foo,omitzero"`
   113  	Foo2 [2]float64 `json:"foo2,omitzero"`
   114  
   115  	Br bool `json:"br"`
   116  	Bo bool `json:"bo,omitzero"`
   117  
   118  	Ur uint `json:"ur"`
   119  	Uo uint `json:"uo,omitzero"`
   120  
   121  	Str struct{} `json:"str"`
   122  	Sto struct{} `json:"sto,omitzero"`
   123  
   124  	Time      time.Time     `json:"time,omitzero"`
   125  	TimeLocal time.Time     `json:"timelocal,omitzero"`
   126  	Nzs       NonZeroStruct `json:"nzs,omitzero"`
   127  
   128  	NilIsZeroer    isZeroer       `json:"niliszeroer,omitzero"`    // nil interface
   129  	NonNilIsZeroer isZeroer       `json:"nonniliszeroer,omitzero"` // non-nil interface
   130  	NoPanicStruct0 isZeroer       `json:"nps0,omitzero"`           // non-nil interface with nil pointer
   131  	NoPanicStruct1 isZeroer       `json:"nps1,omitzero"`           // non-nil interface with non-nil pointer
   132  	NoPanicStruct2 *NoPanicStruct `json:"nps2,omitzero"`           // nil pointer
   133  	NoPanicStruct3 *NoPanicStruct `json:"nps3,omitzero"`           // non-nil pointer
   134  	NoPanicStruct4 NoPanicStruct  `json:"nps4,omitzero"`           // concrete type
   135  }
   136  
   137  func TestOmitZero(t *testing.T) {
   138  	const want = `{
   139   "sr": "",
   140   "omitzero": 0,
   141   "slr": null,
   142   "slononnil": [],
   143   "mr": {},
   144   "Mo": {},
   145   "fr": 0,
   146   "br": false,
   147   "ur": 0,
   148   "str": {},
   149   "nzs": {},
   150   "nps1": {},
   151   "nps3": {},
   152   "nps4": {}
   153  }`
   154  	var o OptionalsZero
   155  	o.Sw = "something"
   156  	o.SloNonNil = make([]string, 0)
   157  	o.Mr = map[string]any{}
   158  	o.Mo = map[string]any{}
   159  
   160  	o.Foo = -0
   161  	o.Foo2 = [2]float64{+0, -0}
   162  
   163  	o.TimeLocal = time.Time{}.Local()
   164  
   165  	o.NonNilIsZeroer = time.Time{}
   166  	o.NoPanicStruct0 = (*NoPanicStruct)(nil)
   167  	o.NoPanicStruct1 = &NoPanicStruct{}
   168  	o.NoPanicStruct3 = &NoPanicStruct{}
   169  
   170  	got, err := MarshalIndent(&o, "", " ")
   171  	if err != nil {
   172  		t.Fatalf("MarshalIndent error: %v", err)
   173  	}
   174  	if got := string(got); got != want {
   175  		t.Errorf("MarshalIndent:\n\tgot:  %s\n\twant: %s\n", indentNewlines(got), indentNewlines(want))
   176  	}
   177  }
   178  
   179  func TestOmitZeroMap(t *testing.T) {
   180  	const want = `{
   181   "foo": {
   182    "sr": "",
   183    "omitzero": 0,
   184    "slr": null,
   185    "mr": null,
   186    "fr": 0,
   187    "br": false,
   188    "ur": 0,
   189    "str": {},
   190    "nzs": {},
   191    "nps4": {}
   192   }
   193  }`
   194  	m := map[string]OptionalsZero{"foo": {}}
   195  	got, err := MarshalIndent(m, "", " ")
   196  	if err != nil {
   197  		t.Fatalf("MarshalIndent error: %v", err)
   198  	}
   199  	if got := string(got); got != want {
   200  		fmt.Println(got)
   201  		t.Errorf("MarshalIndent:\n\tgot:  %s\n\twant: %s\n", indentNewlines(got), indentNewlines(want))
   202  	}
   203  }
   204  
   205  type OptionalsEmptyZero struct {
   206  	Sr string `json:"sr"`
   207  	So string `json:"so,omitempty,omitzero"`
   208  	Sw string `json:"-"`
   209  
   210  	Io int `json:"io,omitempty,omitzero"`
   211  
   212  	Slr       []string `json:"slr,random"`
   213  	Slo       []string `json:"slo,omitempty,omitzero"`
   214  	SloNonNil []string `json:"slononnil,omitempty,omitzero"`
   215  
   216  	Mr map[string]any `json:"mr"`
   217  	Mo map[string]any `json:",omitempty,omitzero"`
   218  
   219  	Fr float64 `json:"fr"`
   220  	Fo float64 `json:"fo,omitempty,omitzero"`
   221  
   222  	Br bool `json:"br"`
   223  	Bo bool `json:"bo,omitempty,omitzero"`
   224  
   225  	Ur uint `json:"ur"`
   226  	Uo uint `json:"uo,omitempty,omitzero"`
   227  
   228  	Str struct{} `json:"str"`
   229  	Sto struct{} `json:"sto,omitempty,omitzero"`
   230  
   231  	Time time.Time     `json:"time,omitempty,omitzero"`
   232  	Nzs  NonZeroStruct `json:"nzs,omitempty,omitzero"`
   233  }
   234  
   235  func TestOmitEmptyZero(t *testing.T) {
   236  	const want = `{
   237   "sr": "",
   238   "slr": null,
   239   "mr": {},
   240   "fr": 0,
   241   "br": false,
   242   "ur": 0,
   243   "str": {},
   244   "nzs": {}
   245  }`
   246  	var o OptionalsEmptyZero
   247  	o.Sw = "something"
   248  	o.SloNonNil = make([]string, 0)
   249  	o.Mr = map[string]any{}
   250  	o.Mo = map[string]any{}
   251  
   252  	got, err := MarshalIndent(&o, "", " ")
   253  	if err != nil {
   254  		t.Fatalf("MarshalIndent error: %v", err)
   255  	}
   256  	if got := string(got); got != want {
   257  		t.Errorf("MarshalIndent:\n\tgot:  %s\n\twant: %s\n", indentNewlines(got), indentNewlines(want))
   258  	}
   259  }
   260  
   261  type StringTag struct {
   262  	BoolStr    bool    `json:",string"`
   263  	IntStr     int64   `json:",string"`
   264  	UintptrStr uintptr `json:",string"`
   265  	StrStr     string  `json:",string"`
   266  	NumberStr  Number  `json:",string"`
   267  }
   268  
   269  func TestRoundtripStringTag(t *testing.T) {
   270  	tests := []struct {
   271  		CaseName
   272  		in   StringTag
   273  		want string // empty to just test that we roundtrip
   274  	}{{
   275  		CaseName: Name("AllTypes"),
   276  		in: StringTag{
   277  			BoolStr:    true,
   278  			IntStr:     42,
   279  			UintptrStr: 44,
   280  			StrStr:     "xzbit",
   281  			NumberStr:  "46",
   282  		},
   283  		want: `{
   284  	"BoolStr": "true",
   285  	"IntStr": "42",
   286  	"UintptrStr": "44",
   287  	"StrStr": "\"xzbit\"",
   288  	"NumberStr": "46"
   289  }`,
   290  	}, {
   291  		// See golang.org/issues/38173.
   292  		CaseName: Name("StringDoubleEscapes"),
   293  		in: StringTag{
   294  			StrStr:    "\b\f\n\r\t\"\\",
   295  			NumberStr: "0", // just to satisfy the roundtrip
   296  		},
   297  		want: `{
   298  	"BoolStr": "false",
   299  	"IntStr": "0",
   300  	"UintptrStr": "0",
   301  	"StrStr": "\"\\b\\f\\n\\r\\t\\\"\\\\\"",
   302  	"NumberStr": "0"
   303  }`,
   304  	}}
   305  	for _, tt := range tests {
   306  		t.Run(tt.Name, func(t *testing.T) {
   307  			got, err := MarshalIndent(&tt.in, "", "\t")
   308  			if err != nil {
   309  				t.Fatalf("%s: MarshalIndent error: %v", tt.Where, err)
   310  			}
   311  			if got := string(got); got != tt.want {
   312  				t.Fatalf("%s: MarshalIndent:\n\tgot:  %s\n\twant: %s", tt.Where, stripWhitespace(got), stripWhitespace(tt.want))
   313  			}
   314  
   315  			// Verify that it round-trips.
   316  			var s2 StringTag
   317  			if err := Unmarshal(got, &s2); err != nil {
   318  				t.Fatalf("%s: Decode error: %v", tt.Where, err)
   319  			}
   320  			if !reflect.DeepEqual(s2, tt.in) {
   321  				t.Fatalf("%s: Decode:\n\tinput: %s\n\tgot:  %#v\n\twant: %#v", tt.Where, indentNewlines(string(got)), s2, tt.in)
   322  			}
   323  		})
   324  	}
   325  }
   326  
   327  // byte slices are special even if they're renamed types.
   328  type renamedByte byte
   329  type renamedByteSlice []byte
   330  type renamedRenamedByteSlice []renamedByte
   331  
   332  func TestEncodeRenamedByteSlice(t *testing.T) {
   333  	s := renamedByteSlice("abc")
   334  	got, err := Marshal(s)
   335  	if err != nil {
   336  		t.Fatalf("Marshal error: %v", err)
   337  	}
   338  	want := `"YWJj"`
   339  	if string(got) != want {
   340  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   341  	}
   342  	r := renamedRenamedByteSlice("abc")
   343  	got, err = Marshal(r)
   344  	if err != nil {
   345  		t.Fatalf("Marshal error: %v", err)
   346  	}
   347  	if string(got) != want {
   348  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   349  	}
   350  }
   351  
   352  type SamePointerNoCycle struct {
   353  	Ptr1, Ptr2 *SamePointerNoCycle
   354  }
   355  
   356  var samePointerNoCycle = &SamePointerNoCycle{}
   357  
   358  type PointerCycle struct {
   359  	Ptr *PointerCycle
   360  }
   361  
   362  var pointerCycle = &PointerCycle{}
   363  
   364  type PointerCycleIndirect struct {
   365  	Ptrs []any
   366  }
   367  
   368  type RecursiveSlice []RecursiveSlice
   369  
   370  var (
   371  	pointerCycleIndirect = &PointerCycleIndirect{}
   372  	mapCycle             = make(map[string]any)
   373  	sliceCycle           = []any{nil}
   374  	sliceNoCycle         = []any{nil, nil}
   375  	recursiveSliceCycle  = []RecursiveSlice{nil}
   376  )
   377  
   378  func init() {
   379  	ptr := &SamePointerNoCycle{}
   380  	samePointerNoCycle.Ptr1 = ptr
   381  	samePointerNoCycle.Ptr2 = ptr
   382  
   383  	pointerCycle.Ptr = pointerCycle
   384  	pointerCycleIndirect.Ptrs = []any{pointerCycleIndirect}
   385  
   386  	mapCycle["x"] = mapCycle
   387  	sliceCycle[0] = sliceCycle
   388  	sliceNoCycle[1] = sliceNoCycle[:1]
   389  	const startDetectingCyclesAfter = 1e3
   390  	for i := startDetectingCyclesAfter; i > 0; i-- {
   391  		sliceNoCycle = []any{sliceNoCycle}
   392  	}
   393  	recursiveSliceCycle[0] = recursiveSliceCycle
   394  }
   395  
   396  func TestSamePointerNoCycle(t *testing.T) {
   397  	if _, err := Marshal(samePointerNoCycle); err != nil {
   398  		t.Fatalf("Marshal error: %v", err)
   399  	}
   400  }
   401  
   402  func TestSliceNoCycle(t *testing.T) {
   403  	if _, err := Marshal(sliceNoCycle); err != nil {
   404  		t.Fatalf("Marshal error: %v", err)
   405  	}
   406  }
   407  
   408  func TestUnsupportedValues(t *testing.T) {
   409  	tests := []struct {
   410  		CaseName
   411  		in any
   412  	}{
   413  		{Name(""), math.NaN()},
   414  		{Name(""), math.Inf(-1)},
   415  		{Name(""), math.Inf(1)},
   416  		{Name(""), pointerCycle},
   417  		{Name(""), pointerCycleIndirect},
   418  		{Name(""), mapCycle},
   419  		{Name(""), sliceCycle},
   420  		{Name(""), recursiveSliceCycle},
   421  	}
   422  	for _, tt := range tests {
   423  		t.Run(tt.Name, func(t *testing.T) {
   424  			if _, err := Marshal(tt.in); err != nil {
   425  				if _, ok := err.(*UnsupportedValueError); !ok {
   426  					t.Errorf("%s: Marshal error:\n\tgot:  %T\n\twant: %T", tt.Where, err, new(UnsupportedValueError))
   427  				}
   428  			} else {
   429  				t.Errorf("%s: Marshal error: got nil, want non-nil", tt.Where)
   430  			}
   431  		})
   432  	}
   433  }
   434  
   435  // Issue 43207
   436  func TestMarshalTextFloatMap(t *testing.T) {
   437  	m := map[textfloat]string{
   438  		textfloat(math.NaN()): "1",
   439  		textfloat(math.NaN()): "1",
   440  	}
   441  	got, err := Marshal(m)
   442  	if err != nil {
   443  		t.Errorf("Marshal error: %v", err)
   444  	}
   445  	want := `{"TF:NaN":"1","TF:NaN":"1"}`
   446  	if string(got) != want {
   447  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   448  	}
   449  }
   450  
   451  // Ref has Marshaler and Unmarshaler methods with pointer receiver.
   452  type Ref int
   453  
   454  func (*Ref) MarshalJSON() ([]byte, error) {
   455  	return []byte(`"ref"`), nil
   456  }
   457  
   458  func (r *Ref) UnmarshalJSON([]byte) error {
   459  	*r = 12
   460  	return nil
   461  }
   462  
   463  // Val has Marshaler methods with value receiver.
   464  type Val int
   465  
   466  func (Val) MarshalJSON() ([]byte, error) {
   467  	return []byte(`"val"`), nil
   468  }
   469  
   470  // RefText has Marshaler and Unmarshaler methods with pointer receiver.
   471  type RefText int
   472  
   473  func (*RefText) MarshalText() ([]byte, error) {
   474  	return []byte(`"ref"`), nil
   475  }
   476  
   477  func (r *RefText) UnmarshalText([]byte) error {
   478  	*r = 13
   479  	return nil
   480  }
   481  
   482  // ValText has Marshaler methods with value receiver.
   483  type ValText int
   484  
   485  func (ValText) MarshalText() ([]byte, error) {
   486  	return []byte(`"val"`), nil
   487  }
   488  
   489  func TestRefValMarshal(t *testing.T) {
   490  	var s = struct {
   491  		R0 Ref
   492  		R1 *Ref
   493  		R2 RefText
   494  		R3 *RefText
   495  		V0 Val
   496  		V1 *Val
   497  		V2 ValText
   498  		V3 *ValText
   499  	}{
   500  		R0: 12,
   501  		R1: new(Ref),
   502  		R2: 14,
   503  		R3: new(RefText),
   504  		V0: 13,
   505  		V1: new(Val),
   506  		V2: 15,
   507  		V3: new(ValText),
   508  	}
   509  	const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
   510  	b, err := Marshal(&s)
   511  	if err != nil {
   512  		t.Fatalf("Marshal error: %v", err)
   513  	}
   514  	if got := string(b); got != want {
   515  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   516  	}
   517  }
   518  
   519  // C implements Marshaler and returns unescaped JSON.
   520  type C int
   521  
   522  func (C) MarshalJSON() ([]byte, error) {
   523  	return []byte(`"<&>"`), nil
   524  }
   525  
   526  // CText implements Marshaler and returns unescaped text.
   527  type CText int
   528  
   529  func (CText) MarshalText() ([]byte, error) {
   530  	return []byte(`"<&>"`), nil
   531  }
   532  
   533  func TestMarshalerEscaping(t *testing.T) {
   534  	var c C
   535  	want := `"\u003c\u0026\u003e"`
   536  	b, err := Marshal(c)
   537  	if err != nil {
   538  		t.Fatalf("Marshal error: %v", err)
   539  	}
   540  	if got := string(b); got != want {
   541  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   542  	}
   543  
   544  	var ct CText
   545  	want = `"\"\u003c\u0026\u003e\""`
   546  	b, err = Marshal(ct)
   547  	if err != nil {
   548  		t.Fatalf("Marshal error: %v", err)
   549  	}
   550  	if got := string(b); got != want {
   551  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   552  	}
   553  }
   554  
   555  func TestAnonymousFields(t *testing.T) {
   556  	tests := []struct {
   557  		CaseName
   558  		makeInput func() any // Function to create input value
   559  		want      string     // Expected JSON output
   560  	}{{
   561  		// Both S1 and S2 have a field named X. From the perspective of S,
   562  		// it is ambiguous which one X refers to.
   563  		// This should not serialize either field.
   564  		CaseName: Name("AmbiguousField"),
   565  		makeInput: func() any {
   566  			type (
   567  				S1 struct{ x, X int }
   568  				S2 struct{ x, X int }
   569  				S  struct {
   570  					S1
   571  					S2
   572  				}
   573  			)
   574  			return S{S1{1, 2}, S2{3, 4}}
   575  		},
   576  		want: `{}`,
   577  	}, {
   578  		CaseName: Name("DominantField"),
   579  		// Both S1 and S2 have a field named X, but since S has an X field as
   580  		// well, it takes precedence over S1.X and S2.X.
   581  		makeInput: func() any {
   582  			type (
   583  				S1 struct{ x, X int }
   584  				S2 struct{ x, X int }
   585  				S  struct {
   586  					S1
   587  					S2
   588  					x, X int
   589  				}
   590  			)
   591  			return S{S1{1, 2}, S2{3, 4}, 5, 6}
   592  		},
   593  		want: `{"X":6}`,
   594  	}, {
   595  		// Unexported embedded field of non-struct type should not be serialized.
   596  		CaseName: Name("UnexportedEmbeddedInt"),
   597  		makeInput: func() any {
   598  			type (
   599  				myInt int
   600  				S     struct{ myInt }
   601  			)
   602  			return S{5}
   603  		},
   604  		want: `{}`,
   605  	}, {
   606  		// Exported embedded field of non-struct type should be serialized.
   607  		CaseName: Name("ExportedEmbeddedInt"),
   608  		makeInput: func() any {
   609  			type (
   610  				MyInt int
   611  				S     struct{ MyInt }
   612  			)
   613  			return S{5}
   614  		},
   615  		want: `{"MyInt":5}`,
   616  	}, {
   617  		// Unexported embedded field of pointer to non-struct type
   618  		// should not be serialized.
   619  		CaseName: Name("UnexportedEmbeddedIntPointer"),
   620  		makeInput: func() any {
   621  			type (
   622  				myInt int
   623  				S     struct{ *myInt }
   624  			)
   625  			s := S{new(myInt)}
   626  			*s.myInt = 5
   627  			return s
   628  		},
   629  		want: `{}`,
   630  	}, {
   631  		// Exported embedded field of pointer to non-struct type
   632  		// should be serialized.
   633  		CaseName: Name("ExportedEmbeddedIntPointer"),
   634  		makeInput: func() any {
   635  			type (
   636  				MyInt int
   637  				S     struct{ *MyInt }
   638  			)
   639  			s := S{new(MyInt)}
   640  			*s.MyInt = 5
   641  			return s
   642  		},
   643  		want: `{"MyInt":5}`,
   644  	}, {
   645  		// Exported fields of embedded structs should have their
   646  		// exported fields be serialized regardless of whether the struct types
   647  		// themselves are exported.
   648  		CaseName: Name("EmbeddedStruct"),
   649  		makeInput: func() any {
   650  			type (
   651  				s1 struct{ x, X int }
   652  				S2 struct{ y, Y int }
   653  				S  struct {
   654  					s1
   655  					S2
   656  				}
   657  			)
   658  			return S{s1{1, 2}, S2{3, 4}}
   659  		},
   660  		want: `{"X":2,"Y":4}`,
   661  	}, {
   662  		// Exported fields of pointers to embedded structs should have their
   663  		// exported fields be serialized regardless of whether the struct types
   664  		// themselves are exported.
   665  		CaseName: Name("EmbeddedStructPointer"),
   666  		makeInput: func() any {
   667  			type (
   668  				s1 struct{ x, X int }
   669  				S2 struct{ y, Y int }
   670  				S  struct {
   671  					*s1
   672  					*S2
   673  				}
   674  			)
   675  			return S{&s1{1, 2}, &S2{3, 4}}
   676  		},
   677  		want: `{"X":2,"Y":4}`,
   678  	}, {
   679  		// Exported fields on embedded unexported structs at multiple levels
   680  		// of nesting should still be serialized.
   681  		CaseName: Name("NestedStructAndInts"),
   682  		makeInput: func() any {
   683  			type (
   684  				MyInt1 int
   685  				MyInt2 int
   686  				myInt  int
   687  				s2     struct {
   688  					MyInt2
   689  					myInt
   690  				}
   691  				s1 struct {
   692  					MyInt1
   693  					myInt
   694  					s2
   695  				}
   696  				S struct {
   697  					s1
   698  					myInt
   699  				}
   700  			)
   701  			return S{s1{1, 2, s2{3, 4}}, 6}
   702  		},
   703  		want: `{"MyInt1":1,"MyInt2":3}`,
   704  	}, {
   705  		// If an anonymous struct pointer field is nil, we should ignore
   706  		// the embedded fields behind it. Not properly doing so may
   707  		// result in the wrong output or reflect panics.
   708  		CaseName: Name("EmbeddedFieldBehindNilPointer"),
   709  		makeInput: func() any {
   710  			type (
   711  				S2 struct{ Field string }
   712  				S  struct{ *S2 }
   713  			)
   714  			return S{}
   715  		},
   716  		want: `{}`,
   717  	}}
   718  
   719  	for _, tt := range tests {
   720  		t.Run(tt.Name, func(t *testing.T) {
   721  			b, err := Marshal(tt.makeInput())
   722  			if err != nil {
   723  				t.Fatalf("%s: Marshal error: %v", tt.Where, err)
   724  			}
   725  			if string(b) != tt.want {
   726  				t.Fatalf("%s: Marshal:\n\tgot:  %s\n\twant: %s", tt.Where, b, tt.want)
   727  			}
   728  		})
   729  	}
   730  }
   731  
   732  type BugA struct {
   733  	S string
   734  }
   735  
   736  type BugB struct {
   737  	BugA
   738  	S string
   739  }
   740  
   741  type BugC struct {
   742  	S string
   743  }
   744  
   745  // Legal Go: We never use the repeated embedded field (S).
   746  type BugX struct {
   747  	A int
   748  	BugA
   749  	BugB
   750  }
   751  
   752  // golang.org/issue/16042.
   753  // Even if a nil interface value is passed in, as long as
   754  // it implements Marshaler, it should be marshaled.
   755  type nilJSONMarshaler string
   756  
   757  func (nm *nilJSONMarshaler) MarshalJSON() ([]byte, error) {
   758  	if nm == nil {
   759  		return Marshal("0zenil0")
   760  	}
   761  	return Marshal("zenil:" + string(*nm))
   762  }
   763  
   764  // golang.org/issue/34235.
   765  // Even if a nil interface value is passed in, as long as
   766  // it implements encoding.TextMarshaler, it should be marshaled.
   767  type nilTextMarshaler string
   768  
   769  func (nm *nilTextMarshaler) MarshalText() ([]byte, error) {
   770  	if nm == nil {
   771  		return []byte("0zenil0"), nil
   772  	}
   773  	return []byte("zenil:" + string(*nm)), nil
   774  }
   775  
   776  // See golang.org/issue/16042 and golang.org/issue/34235.
   777  func TestNilMarshal(t *testing.T) {
   778  	tests := []struct {
   779  		CaseName
   780  		in   any
   781  		want string
   782  	}{
   783  		{Name(""), nil, `null`},
   784  		{Name(""), new(float64), `0`},
   785  		{Name(""), []any(nil), `null`},
   786  		{Name(""), []string(nil), `null`},
   787  		{Name(""), map[string]string(nil), `null`},
   788  		{Name(""), []byte(nil), `null`},
   789  		{Name(""), struct{ M string }{"gopher"}, `{"M":"gopher"}`},
   790  		{Name(""), struct{ M Marshaler }{}, `{"M":null}`},
   791  		{Name(""), struct{ M Marshaler }{(*nilJSONMarshaler)(nil)}, `{"M":"0zenil0"}`},
   792  		{Name(""), struct{ M any }{(*nilJSONMarshaler)(nil)}, `{"M":null}`},
   793  		{Name(""), struct{ M encoding.TextMarshaler }{}, `{"M":null}`},
   794  		{Name(""), struct{ M encoding.TextMarshaler }{(*nilTextMarshaler)(nil)}, `{"M":"0zenil0"}`},
   795  		{Name(""), struct{ M any }{(*nilTextMarshaler)(nil)}, `{"M":null}`},
   796  	}
   797  	for _, tt := range tests {
   798  		t.Run(tt.Name, func(t *testing.T) {
   799  			switch got, err := Marshal(tt.in); {
   800  			case err != nil:
   801  				t.Fatalf("%s: Marshal error: %v", tt.Where, err)
   802  			case string(got) != tt.want:
   803  				t.Fatalf("%s: Marshal:\n\tgot:  %s\n\twant: %s", tt.Where, got, tt.want)
   804  			}
   805  		})
   806  	}
   807  }
   808  
   809  // Issue 5245.
   810  func TestEmbeddedBug(t *testing.T) {
   811  	v := BugB{
   812  		BugA{"A"},
   813  		"B",
   814  	}
   815  	b, err := Marshal(v)
   816  	if err != nil {
   817  		t.Fatal("Marshal error:", err)
   818  	}
   819  	want := `{"S":"B"}`
   820  	got := string(b)
   821  	if got != want {
   822  		t.Fatalf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   823  	}
   824  	// Now check that the duplicate field, S, does not appear.
   825  	x := BugX{
   826  		A: 23,
   827  	}
   828  	b, err = Marshal(x)
   829  	if err != nil {
   830  		t.Fatal("Marshal error:", err)
   831  	}
   832  	want = `{"A":23}`
   833  	got = string(b)
   834  	if got != want {
   835  		t.Fatalf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   836  	}
   837  }
   838  
   839  type BugD struct { // Same as BugA after tagging.
   840  	XXX string `json:"S"`
   841  }
   842  
   843  // BugD's tagged S field should dominate BugA's.
   844  type BugY struct {
   845  	BugA
   846  	BugD
   847  }
   848  
   849  // Test that a field with a tag dominates untagged fields.
   850  func TestTaggedFieldDominates(t *testing.T) {
   851  	v := BugY{
   852  		BugA{"BugA"},
   853  		BugD{"BugD"},
   854  	}
   855  	b, err := Marshal(v)
   856  	if err != nil {
   857  		t.Fatal("Marshal error:", err)
   858  	}
   859  	want := `{"S":"BugD"}`
   860  	got := string(b)
   861  	if got != want {
   862  		t.Fatalf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   863  	}
   864  }
   865  
   866  // There are no tags here, so S should not appear.
   867  type BugZ struct {
   868  	BugA
   869  	BugC
   870  	BugY // Contains a tagged S field through BugD; should not dominate.
   871  }
   872  
   873  func TestDuplicatedFieldDisappears(t *testing.T) {
   874  	v := BugZ{
   875  		BugA{"BugA"},
   876  		BugC{"BugC"},
   877  		BugY{
   878  			BugA{"nested BugA"},
   879  			BugD{"nested BugD"},
   880  		},
   881  	}
   882  	b, err := Marshal(v)
   883  	if err != nil {
   884  		t.Fatal("Marshal error:", err)
   885  	}
   886  	want := `{}`
   887  	got := string(b)
   888  	if got != want {
   889  		t.Fatalf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   890  	}
   891  }
   892  
   893  func TestIssue10281(t *testing.T) {
   894  	type Foo struct {
   895  		N Number
   896  	}
   897  	x := Foo{Number(`invalid`)}
   898  
   899  	if _, err := Marshal(&x); err == nil {
   900  		t.Fatalf("Marshal error: got nil, want non-nil")
   901  	}
   902  }
   903  
   904  func TestMarshalErrorAndReuseEncodeState(t *testing.T) {
   905  	// Disable the GC temporarily to prevent encodeState's in Pool being cleaned away during the test.
   906  	percent := debug.SetGCPercent(-1)
   907  	defer debug.SetGCPercent(percent)
   908  
   909  	// Trigger an error in Marshal with cyclic data.
   910  	type Dummy struct {
   911  		Name string
   912  		Next *Dummy
   913  	}
   914  	dummy := Dummy{Name: "Dummy"}
   915  	dummy.Next = &dummy
   916  	if _, err := Marshal(dummy); err == nil {
   917  		t.Errorf("Marshal error: got nil, want non-nil")
   918  	}
   919  
   920  	type Data struct {
   921  		A string
   922  		I int
   923  	}
   924  	want := Data{A: "a", I: 1}
   925  	b, err := Marshal(want)
   926  	if err != nil {
   927  		t.Errorf("Marshal error: %v", err)
   928  	}
   929  
   930  	var got Data
   931  	if err := Unmarshal(b, &got); err != nil {
   932  		t.Errorf("Unmarshal error: %v", err)
   933  	}
   934  	if got != want {
   935  		t.Errorf("Unmarshal:\n\tgot:  %v\n\twant: %v", got, want)
   936  	}
   937  }
   938  
   939  func TestHTMLEscape(t *testing.T) {
   940  	var b, want bytes.Buffer
   941  	m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
   942  	want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
   943  	HTMLEscape(&b, []byte(m))
   944  	if !bytes.Equal(b.Bytes(), want.Bytes()) {
   945  		t.Errorf("HTMLEscape:\n\tgot:  %s\n\twant: %s", b.Bytes(), want.Bytes())
   946  	}
   947  }
   948  
   949  // golang.org/issue/8582
   950  func TestEncodePointerString(t *testing.T) {
   951  	type stringPointer struct {
   952  		N *int64 `json:"n,string"`
   953  	}
   954  	var n int64 = 42
   955  	b, err := Marshal(stringPointer{N: &n})
   956  	if err != nil {
   957  		t.Fatalf("Marshal error: %v", err)
   958  	}
   959  	if got, want := string(b), `{"n":"42"}`; got != want {
   960  		t.Fatalf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
   961  	}
   962  	var back stringPointer
   963  	switch err = Unmarshal(b, &back); {
   964  	case err != nil:
   965  		t.Fatalf("Unmarshal error: %v", err)
   966  	case back.N == nil:
   967  		t.Fatalf("Unmarshal: back.N = nil, want non-nil")
   968  	case *back.N != 42:
   969  		t.Fatalf("Unmarshal: *back.N = %d, want 42", *back.N)
   970  	}
   971  }
   972  
   973  var encodeStringTests = []struct {
   974  	in  string
   975  	out string
   976  }{
   977  	{"\x00", `"\u0000"`},
   978  	{"\x01", `"\u0001"`},
   979  	{"\x02", `"\u0002"`},
   980  	{"\x03", `"\u0003"`},
   981  	{"\x04", `"\u0004"`},
   982  	{"\x05", `"\u0005"`},
   983  	{"\x06", `"\u0006"`},
   984  	{"\x07", `"\u0007"`},
   985  	{"\x08", `"\b"`},
   986  	{"\x09", `"\t"`},
   987  	{"\x0a", `"\n"`},
   988  	{"\x0b", `"\u000b"`},
   989  	{"\x0c", `"\f"`},
   990  	{"\x0d", `"\r"`},
   991  	{"\x0e", `"\u000e"`},
   992  	{"\x0f", `"\u000f"`},
   993  	{"\x10", `"\u0010"`},
   994  	{"\x11", `"\u0011"`},
   995  	{"\x12", `"\u0012"`},
   996  	{"\x13", `"\u0013"`},
   997  	{"\x14", `"\u0014"`},
   998  	{"\x15", `"\u0015"`},
   999  	{"\x16", `"\u0016"`},
  1000  	{"\x17", `"\u0017"`},
  1001  	{"\x18", `"\u0018"`},
  1002  	{"\x19", `"\u0019"`},
  1003  	{"\x1a", `"\u001a"`},
  1004  	{"\x1b", `"\u001b"`},
  1005  	{"\x1c", `"\u001c"`},
  1006  	{"\x1d", `"\u001d"`},
  1007  	{"\x1e", `"\u001e"`},
  1008  	{"\x1f", `"\u001f"`},
  1009  }
  1010  
  1011  func TestEncodeString(t *testing.T) {
  1012  	for _, tt := range encodeStringTests {
  1013  		b, err := Marshal(tt.in)
  1014  		if err != nil {
  1015  			t.Errorf("Marshal(%q) error: %v", tt.in, err)
  1016  			continue
  1017  		}
  1018  		out := string(b)
  1019  		if out != tt.out {
  1020  			t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out)
  1021  		}
  1022  	}
  1023  }
  1024  
  1025  type jsonbyte byte
  1026  
  1027  func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) }
  1028  
  1029  type textbyte byte
  1030  
  1031  func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) }
  1032  
  1033  type jsonint int
  1034  
  1035  func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) }
  1036  
  1037  type textint int
  1038  
  1039  func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) }
  1040  
  1041  func tenc(format string, a ...any) ([]byte, error) {
  1042  	var buf bytes.Buffer
  1043  	fmt.Fprintf(&buf, format, a...)
  1044  	return buf.Bytes(), nil
  1045  }
  1046  
  1047  type textfloat float64
  1048  
  1049  func (f textfloat) MarshalText() ([]byte, error) { return tenc(`TF:%0.2f`, f) }
  1050  
  1051  // Issue 13783
  1052  func TestEncodeBytekind(t *testing.T) {
  1053  	tests := []struct {
  1054  		CaseName
  1055  		in   any
  1056  		want string
  1057  	}{
  1058  		{Name(""), byte(7), "7"},
  1059  		{Name(""), jsonbyte(7), `{"JB":7}`},
  1060  		{Name(""), textbyte(4), `"TB:4"`},
  1061  		{Name(""), jsonint(5), `{"JI":5}`},
  1062  		{Name(""), textint(1), `"TI:1"`},
  1063  		{Name(""), []byte{0, 1}, `"AAE="`},
  1064  		{Name(""), []jsonbyte{0, 1}, `[{"JB":0},{"JB":1}]`},
  1065  		{Name(""), [][]jsonbyte{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`},
  1066  		{Name(""), []textbyte{2, 3}, `["TB:2","TB:3"]`},
  1067  		{Name(""), []jsonint{5, 4}, `[{"JI":5},{"JI":4}]`},
  1068  		{Name(""), []textint{9, 3}, `["TI:9","TI:3"]`},
  1069  		{Name(""), []int{9, 3}, `[9,3]`},
  1070  		{Name(""), []textfloat{12, 3}, `["TF:12.00","TF:3.00"]`},
  1071  	}
  1072  	for _, tt := range tests {
  1073  		t.Run(tt.Name, func(t *testing.T) {
  1074  			b, err := Marshal(tt.in)
  1075  			if err != nil {
  1076  				t.Errorf("%s: Marshal error: %v", tt.Where, err)
  1077  			}
  1078  			got, want := string(b), tt.want
  1079  			if got != want {
  1080  				t.Errorf("%s: Marshal:\n\tgot:  %s\n\twant: %s", tt.Where, got, want)
  1081  			}
  1082  		})
  1083  	}
  1084  }
  1085  
  1086  func TestTextMarshalerMapKeysAreSorted(t *testing.T) {
  1087  	got, err := Marshal(map[unmarshalerText]int{
  1088  		{"x", "y"}: 1,
  1089  		{"y", "x"}: 2,
  1090  		{"a", "z"}: 3,
  1091  		{"z", "a"}: 4,
  1092  	})
  1093  	if err != nil {
  1094  		t.Fatalf("Marshal error: %v", err)
  1095  	}
  1096  	const want = `{"a:z":3,"x:y":1,"y:x":2,"z:a":4}`
  1097  	if string(got) != want {
  1098  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
  1099  	}
  1100  }
  1101  
  1102  // https://golang.org/issue/33675
  1103  func TestNilMarshalerTextMapKey(t *testing.T) {
  1104  	got, err := Marshal(map[*unmarshalerText]int{
  1105  		(*unmarshalerText)(nil): 1,
  1106  		{"A", "B"}:              2,
  1107  	})
  1108  	if err != nil {
  1109  		t.Fatalf("Marshal error: %v", err)
  1110  	}
  1111  	const want = `{"":1,"A:B":2}`
  1112  	if string(got) != want {
  1113  		t.Errorf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
  1114  	}
  1115  }
  1116  
  1117  var re = regexp.MustCompile
  1118  
  1119  // syntactic checks on form of marshaled floating point numbers.
  1120  var badFloatREs = []*regexp.Regexp{
  1121  	re(`p`),                     // no binary exponential notation
  1122  	re(`^\+`),                   // no leading + sign
  1123  	re(`^-?0[^.]`),              // no unnecessary leading zeros
  1124  	re(`^-?\.`),                 // leading zero required before decimal point
  1125  	re(`\.(e|$)`),               // no trailing decimal
  1126  	re(`\.[0-9]+0(e|$)`),        // no trailing zero in fraction
  1127  	re(`^-?(0|[0-9]{2,})\..*e`), // exponential notation must have normalized mantissa
  1128  	re(`e[0-9]`),                // positive exponent must be signed
  1129  	re(`e[+-]0`),                // exponent must not have leading zeros
  1130  	re(`e-[1-6]$`),              // not tiny enough for exponential notation
  1131  	re(`e+(.|1.|20)$`),          // not big enough for exponential notation
  1132  	re(`^-?0\.0000000`),         // too tiny, should use exponential notation
  1133  	re(`^-?[0-9]{22}`),          // too big, should use exponential notation
  1134  	re(`[1-9][0-9]{16}[1-9]`),   // too many significant digits in integer
  1135  	re(`[1-9][0-9.]{17}[1-9]`),  // too many significant digits in decimal
  1136  	// below here for float32 only
  1137  	re(`[1-9][0-9]{8}[1-9]`),  // too many significant digits in integer
  1138  	re(`[1-9][0-9.]{9}[1-9]`), // too many significant digits in decimal
  1139  }
  1140  
  1141  func TestMarshalFloat(t *testing.T) {
  1142  	t.Parallel()
  1143  	nfail := 0
  1144  	test := func(f float64, bits int) {
  1145  		vf := any(f)
  1146  		if bits == 32 {
  1147  			f = float64(float32(f)) // round
  1148  			vf = float32(f)
  1149  		}
  1150  		bout, err := Marshal(vf)
  1151  		if err != nil {
  1152  			t.Errorf("Marshal(%T(%g)) error: %v", vf, vf, err)
  1153  			nfail++
  1154  			return
  1155  		}
  1156  		out := string(bout)
  1157  
  1158  		// result must convert back to the same float
  1159  		g, err := strconv.ParseFloat(out, bits)
  1160  		if err != nil {
  1161  			t.Errorf("ParseFloat(%q) error: %v", out, err)
  1162  			nfail++
  1163  			return
  1164  		}
  1165  		if f != g || fmt.Sprint(f) != fmt.Sprint(g) { // fmt.Sprint handles ±0
  1166  			t.Errorf("ParseFloat(%q):\n\tgot:  %g\n\twant: %g", out, float32(g), vf)
  1167  			nfail++
  1168  			return
  1169  		}
  1170  
  1171  		bad := badFloatREs
  1172  		if bits == 64 {
  1173  			bad = bad[:len(bad)-2]
  1174  		}
  1175  		for _, re := range bad {
  1176  			if re.MatchString(out) {
  1177  				t.Errorf("Marshal(%T(%g)) = %q; must not match /%s/", vf, vf, out, re)
  1178  				nfail++
  1179  				return
  1180  			}
  1181  		}
  1182  	}
  1183  
  1184  	var (
  1185  		bigger  = math.Inf(+1)
  1186  		smaller = math.Inf(-1)
  1187  	)
  1188  
  1189  	var digits = "1.2345678901234567890123"
  1190  	for i := len(digits); i >= 2; i-- {
  1191  		if testing.Short() && i < len(digits)-4 {
  1192  			break
  1193  		}
  1194  		for exp := -30; exp <= 30; exp++ {
  1195  			for _, sign := range "+-" {
  1196  				for bits := 32; bits <= 64; bits += 32 {
  1197  					s := fmt.Sprintf("%c%se%d", sign, digits[:i], exp)
  1198  					f, err := strconv.ParseFloat(s, bits)
  1199  					if err != nil {
  1200  						log.Fatal(err)
  1201  					}
  1202  					next := math.Nextafter
  1203  					if bits == 32 {
  1204  						next = func(g, h float64) float64 {
  1205  							return float64(math.Nextafter32(float32(g), float32(h)))
  1206  						}
  1207  					}
  1208  					test(f, bits)
  1209  					test(next(f, bigger), bits)
  1210  					test(next(f, smaller), bits)
  1211  					if nfail > 50 {
  1212  						t.Fatalf("stopping test early")
  1213  					}
  1214  				}
  1215  			}
  1216  		}
  1217  	}
  1218  	test(0, 64)
  1219  	test(math.Copysign(0, -1), 64)
  1220  	test(0, 32)
  1221  	test(math.Copysign(0, -1), 32)
  1222  }
  1223  
  1224  func TestMarshalRawMessageValue(t *testing.T) {
  1225  	type (
  1226  		T1 struct {
  1227  			M RawMessage `json:",omitempty"`
  1228  		}
  1229  		T2 struct {
  1230  			M *RawMessage `json:",omitempty"`
  1231  		}
  1232  	)
  1233  
  1234  	var (
  1235  		rawNil   = RawMessage(nil)
  1236  		rawEmpty = RawMessage([]byte{})
  1237  		rawText  = RawMessage([]byte(`"foo"`))
  1238  	)
  1239  
  1240  	tests := []struct {
  1241  		CaseName
  1242  		in   any
  1243  		want string
  1244  		ok   bool
  1245  	}{
  1246  		// Test with nil RawMessage.
  1247  		{Name(""), rawNil, "null", true},
  1248  		{Name(""), &rawNil, "null", true},
  1249  		{Name(""), []any{rawNil}, "[null]", true},
  1250  		{Name(""), &[]any{rawNil}, "[null]", true},
  1251  		{Name(""), []any{&rawNil}, "[null]", true},
  1252  		{Name(""), &[]any{&rawNil}, "[null]", true},
  1253  		{Name(""), struct{ M RawMessage }{rawNil}, `{"M":null}`, true},
  1254  		{Name(""), &struct{ M RawMessage }{rawNil}, `{"M":null}`, true},
  1255  		{Name(""), struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true},
  1256  		{Name(""), &struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true},
  1257  		{Name(""), map[string]any{"M": rawNil}, `{"M":null}`, true},
  1258  		{Name(""), &map[string]any{"M": rawNil}, `{"M":null}`, true},
  1259  		{Name(""), map[string]any{"M": &rawNil}, `{"M":null}`, true},
  1260  		{Name(""), &map[string]any{"M": &rawNil}, `{"M":null}`, true},
  1261  		{Name(""), T1{rawNil}, "{}", true},
  1262  		{Name(""), T2{&rawNil}, `{"M":null}`, true},
  1263  		{Name(""), &T1{rawNil}, "{}", true},
  1264  		{Name(""), &T2{&rawNil}, `{"M":null}`, true},
  1265  
  1266  		// Test with empty, but non-nil, RawMessage.
  1267  		{Name(""), rawEmpty, "", false},
  1268  		{Name(""), &rawEmpty, "", false},
  1269  		{Name(""), []any{rawEmpty}, "", false},
  1270  		{Name(""), &[]any{rawEmpty}, "", false},
  1271  		{Name(""), []any{&rawEmpty}, "", false},
  1272  		{Name(""), &[]any{&rawEmpty}, "", false},
  1273  		{Name(""), struct{ X RawMessage }{rawEmpty}, "", false},
  1274  		{Name(""), &struct{ X RawMessage }{rawEmpty}, "", false},
  1275  		{Name(""), struct{ X *RawMessage }{&rawEmpty}, "", false},
  1276  		{Name(""), &struct{ X *RawMessage }{&rawEmpty}, "", false},
  1277  		{Name(""), map[string]any{"nil": rawEmpty}, "", false},
  1278  		{Name(""), &map[string]any{"nil": rawEmpty}, "", false},
  1279  		{Name(""), map[string]any{"nil": &rawEmpty}, "", false},
  1280  		{Name(""), &map[string]any{"nil": &rawEmpty}, "", false},
  1281  		{Name(""), T1{rawEmpty}, "{}", true},
  1282  		{Name(""), T2{&rawEmpty}, "", false},
  1283  		{Name(""), &T1{rawEmpty}, "{}", true},
  1284  		{Name(""), &T2{&rawEmpty}, "", false},
  1285  
  1286  		// Test with RawMessage with some text.
  1287  		//
  1288  		// The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo".
  1289  		// This behavior was intentionally changed in Go 1.8.
  1290  		// See https://golang.org/issues/14493#issuecomment-255857318
  1291  		{Name(""), rawText, `"foo"`, true}, // Issue6458
  1292  		{Name(""), &rawText, `"foo"`, true},
  1293  		{Name(""), []any{rawText}, `["foo"]`, true},  // Issue6458
  1294  		{Name(""), &[]any{rawText}, `["foo"]`, true}, // Issue6458
  1295  		{Name(""), []any{&rawText}, `["foo"]`, true},
  1296  		{Name(""), &[]any{&rawText}, `["foo"]`, true},
  1297  		{Name(""), struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true}, // Issue6458
  1298  		{Name(""), &struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true},
  1299  		{Name(""), struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true},
  1300  		{Name(""), &struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true},
  1301  		{Name(""), map[string]any{"M": rawText}, `{"M":"foo"}`, true},  // Issue6458
  1302  		{Name(""), &map[string]any{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458
  1303  		{Name(""), map[string]any{"M": &rawText}, `{"M":"foo"}`, true},
  1304  		{Name(""), &map[string]any{"M": &rawText}, `{"M":"foo"}`, true},
  1305  		{Name(""), T1{rawText}, `{"M":"foo"}`, true}, // Issue6458
  1306  		{Name(""), T2{&rawText}, `{"M":"foo"}`, true},
  1307  		{Name(""), &T1{rawText}, `{"M":"foo"}`, true},
  1308  		{Name(""), &T2{&rawText}, `{"M":"foo"}`, true},
  1309  	}
  1310  
  1311  	for _, tt := range tests {
  1312  		t.Run(tt.Name, func(t *testing.T) {
  1313  			b, err := Marshal(tt.in)
  1314  			if ok := (err == nil); ok != tt.ok {
  1315  				if err != nil {
  1316  					t.Errorf("%s: Marshal error: %v", tt.Where, err)
  1317  				} else {
  1318  					t.Errorf("%s: Marshal error: got nil, want non-nil", tt.Where)
  1319  				}
  1320  			}
  1321  			if got := string(b); got != tt.want {
  1322  				t.Errorf("%s: Marshal:\n\tinput: %#v\n\tgot:  %s\n\twant: %s", tt.Where, tt.in, got, tt.want)
  1323  			}
  1324  		})
  1325  	}
  1326  }
  1327  
  1328  type marshalPanic struct{}
  1329  
  1330  func (marshalPanic) MarshalJSON() ([]byte, error) { panic(0xdead) }
  1331  
  1332  func TestMarshalPanic(t *testing.T) {
  1333  	defer func() {
  1334  		if got := recover(); !reflect.DeepEqual(got, 0xdead) {
  1335  			t.Errorf("panic() = (%T)(%v), want 0xdead", got, got)
  1336  		}
  1337  	}()
  1338  	Marshal(&marshalPanic{})
  1339  	t.Error("Marshal should have panicked")
  1340  }
  1341  
  1342  func TestMarshalUncommonFieldNames(t *testing.T) {
  1343  	v := struct {
  1344  		A0, À, Aβ int
  1345  	}{}
  1346  	b, err := Marshal(v)
  1347  	if err != nil {
  1348  		t.Fatal("Marshal error:", err)
  1349  	}
  1350  	want := `{"A0":0,"À":0,"Aβ":0}`
  1351  	got := string(b)
  1352  	if got != want {
  1353  		t.Fatalf("Marshal:\n\tgot:  %s\n\twant: %s", got, want)
  1354  	}
  1355  }
  1356  
  1357  func TestMarshalerError(t *testing.T) {
  1358  	s := "test variable"
  1359  	st := reflect.TypeOf(s)
  1360  	const errText = "json: test error"
  1361  
  1362  	tests := []struct {
  1363  		CaseName
  1364  		err  *MarshalerError
  1365  		want string
  1366  	}{{
  1367  		Name(""),
  1368  		&MarshalerError{st, fmt.Errorf(errText), ""},
  1369  		"json: error calling MarshalJSON for type " + st.String() + ": " + errText,
  1370  	}, {
  1371  		Name(""),
  1372  		&MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"},
  1373  		"json: error calling TestMarshalerError for type " + st.String() + ": " + errText,
  1374  	}}
  1375  
  1376  	for _, tt := range tests {
  1377  		t.Run(tt.Name, func(t *testing.T) {
  1378  			got := tt.err.Error()
  1379  			if got != tt.want {
  1380  				t.Errorf("%s: Error:\n\tgot:  %s\n\twant: %s", tt.Where, got, tt.want)
  1381  			}
  1382  		})
  1383  	}
  1384  }
  1385  
  1386  type marshaledValue string
  1387  
  1388  func (v marshaledValue) MarshalJSON() ([]byte, error) {
  1389  	return []byte(v), nil
  1390  }
  1391  
  1392  func TestIssue63379(t *testing.T) {
  1393  	for _, v := range []string{
  1394  		"[]<",
  1395  		"[]>",
  1396  		"[]&",
  1397  		"[]\u2028",
  1398  		"[]\u2029",
  1399  		"{}<",
  1400  		"{}>",
  1401  		"{}&",
  1402  		"{}\u2028",
  1403  		"{}\u2029",
  1404  	} {
  1405  		_, err := Marshal(marshaledValue(v))
  1406  		if err == nil {
  1407  			t.Errorf("expected error for %q", v)
  1408  		}
  1409  	}
  1410  }
  1411  

View as plain text