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

View as plain text