github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/encode_test.go (about)

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