github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/encode_test.go (about)

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