git.lukeshu.com/go/lowmemjson@v0.3.9-0.20230723050957-72f6d13f6fb2/compat/json/borrowed_encode_test.go (about)

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