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

View as plain text