...

Source file src/github.com/evanphx/json-patch/v5/internal/json/encode_test.go

Documentation: github.com/evanphx/json-patch/v5/internal/json

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

View as plain text