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

View as plain text