github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/encoding/json/encode.go (about) 1 // Copyright 2010 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 implements encoding and decoding of JSON as defined in 6 // RFC 7159. The mapping between JSON and Go values is described 7 // in the documentation for the Marshal and Unmarshal functions. 8 // 9 // See "JSON and Go" for an introduction to this package: 10 // https://golang.org/doc/articles/json_and_go.html 11 package json 12 13 import ( 14 "bytes" 15 "encoding" 16 "encoding/base64" 17 "fmt" 18 "math" 19 "reflect" 20 "slices" 21 "sort" 22 "strconv" 23 "strings" 24 "sync" 25 "unicode" 26 "unicode/utf8" 27 ) 28 29 // Marshal returns the JSON encoding of v. 30 // 31 // Marshal traverses the value v recursively. 32 // If an encountered value implements [Marshaler] 33 // and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] 34 // to produce JSON. If no [Marshaler.MarshalJSON] method is present but the 35 // value implements [encoding.TextMarshaler] instead, Marshal calls 36 // [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. 37 // The nil pointer exception is not strictly necessary 38 // but mimics a similar, necessary exception in the behavior of 39 // [Unmarshaler.UnmarshalJSON]. 40 // 41 // Otherwise, Marshal uses the following type-dependent default encodings: 42 // 43 // Boolean values encode as JSON booleans. 44 // 45 // Floating point, integer, and [Number] values encode as JSON numbers. 46 // NaN and +/-Inf values will return an [UnsupportedValueError]. 47 // 48 // String values encode as JSON strings coerced to valid UTF-8, 49 // replacing invalid bytes with the Unicode replacement rune. 50 // So that the JSON will be safe to embed inside HTML <script> tags, 51 // the string is encoded using [HTMLEscape], 52 // which replaces "<", ">", "&", U+2028, and U+2029 are escaped 53 // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". 54 // This replacement can be disabled when using an [Encoder], 55 // by calling [Encoder.SetEscapeHTML](false). 56 // 57 // Array and slice values encode as JSON arrays, except that 58 // []byte encodes as a base64-encoded string, and a nil slice 59 // encodes as the null JSON value. 60 // 61 // Struct values encode as JSON objects. 62 // Each exported struct field becomes a member of the object, using the 63 // field name as the object key, unless the field is omitted for one of the 64 // reasons given below. 65 // 66 // The encoding of each struct field can be customized by the format string 67 // stored under the "json" key in the struct field's tag. 68 // The format string gives the name of the field, possibly followed by a 69 // comma-separated list of options. The name may be empty in order to 70 // specify options without overriding the default field name. 71 // 72 // The "omitempty" option specifies that the field should be omitted 73 // from the encoding if the field has an empty value, defined as 74 // false, 0, a nil pointer, a nil interface value, and any empty array, 75 // slice, map, or string. 76 // 77 // As a special case, if the field tag is "-", the field is always omitted. 78 // Note that a field with name "-" can still be generated using the tag "-,". 79 // 80 // Examples of struct field tags and their meanings: 81 // 82 // // Field appears in JSON as key "myName". 83 // Field int `json:"myName"` 84 // 85 // // Field appears in JSON as key "myName" and 86 // // the field is omitted from the object if its value is empty, 87 // // as defined above. 88 // Field int `json:"myName,omitempty"` 89 // 90 // // Field appears in JSON as key "Field" (the default), but 91 // // the field is skipped if empty. 92 // // Note the leading comma. 93 // Field int `json:",omitempty"` 94 // 95 // // Field is ignored by this package. 96 // Field int `json:"-"` 97 // 98 // // Field appears in JSON as key "-". 99 // Field int `json:"-,"` 100 // 101 // The "string" option signals that a field is stored as JSON inside a 102 // JSON-encoded string. It applies only to fields of string, floating point, 103 // integer, or boolean types. This extra level of encoding is sometimes used 104 // when communicating with JavaScript programs: 105 // 106 // Int64String int64 `json:",string"` 107 // 108 // The key name will be used if it's a non-empty string consisting of 109 // only Unicode letters, digits, and ASCII punctuation except quotation 110 // marks, backslash, and comma. 111 // 112 // Embedded struct fields are usually marshaled as if their inner exported fields 113 // were fields in the outer struct, subject to the usual Go visibility rules amended 114 // as described in the next paragraph. 115 // An anonymous struct field with a name given in its JSON tag is treated as 116 // having that name, rather than being anonymous. 117 // An anonymous struct field of interface type is treated the same as having 118 // that type as its name, rather than being anonymous. 119 // 120 // The Go visibility rules for struct fields are amended for JSON when 121 // deciding which field to marshal or unmarshal. If there are 122 // multiple fields at the same level, and that level is the least 123 // nested (and would therefore be the nesting level selected by the 124 // usual Go rules), the following extra rules apply: 125 // 126 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, 127 // even if there are multiple untagged fields that would otherwise conflict. 128 // 129 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 130 // 131 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 132 // 133 // Handling of anonymous struct fields is new in Go 1.1. 134 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of 135 // an anonymous struct field in both current and earlier versions, give the field 136 // a JSON tag of "-". 137 // 138 // Map values encode as JSON objects. The map's key type must either be a 139 // string, an integer type, or implement [encoding.TextMarshaler]. The map keys 140 // are sorted and used as JSON object keys by applying the following rules, 141 // subject to the UTF-8 coercion described for string values above: 142 // - keys of any string type are used directly 143 // - [encoding.TextMarshalers] are marshaled 144 // - integer keys are converted to strings 145 // 146 // Pointer values encode as the value pointed to. 147 // A nil pointer encodes as the null JSON value. 148 // 149 // Interface values encode as the value contained in the interface. 150 // A nil interface value encodes as the null JSON value. 151 // 152 // Channel, complex, and function values cannot be encoded in JSON. 153 // Attempting to encode such a value causes Marshal to return 154 // an [UnsupportedTypeError]. 155 // 156 // JSON cannot represent cyclic data structures and Marshal does not 157 // handle them. Passing cyclic structures to Marshal will result in 158 // an error. 159 func Marshal(v any) ([]byte, error) { 160 e := newEncodeState() 161 defer encodeStatePool.Put(e) 162 163 err := e.marshal(v, encOpts{escapeHTML: true}) 164 if err != nil { 165 return nil, err 166 } 167 buf := append([]byte(nil), e.Bytes()...) 168 169 return buf, nil 170 } 171 172 // MarshalIndent is like [Marshal] but applies [Indent] to format the output. 173 // Each JSON element in the output will begin on a new line beginning with prefix 174 // followed by one or more copies of indent according to the indentation nesting. 175 func MarshalIndent(v any, prefix, indent string) ([]byte, error) { 176 b, err := Marshal(v) 177 if err != nil { 178 return nil, err 179 } 180 b2 := make([]byte, 0, indentGrowthFactor*len(b)) 181 b2, err = appendIndent(b2, b, prefix, indent) 182 if err != nil { 183 return nil, err 184 } 185 return b2, nil 186 } 187 188 // Marshaler is the interface implemented by types that 189 // can marshal themselves into valid JSON. 190 type Marshaler interface { 191 MarshalJSON() ([]byte, error) 192 } 193 194 // An UnsupportedTypeError is returned by [Marshal] when attempting 195 // to encode an unsupported value type. 196 type UnsupportedTypeError struct { 197 Type reflect.Type 198 } 199 200 func (e *UnsupportedTypeError) Error() string { 201 return "json: unsupported type: " + e.Type.String() 202 } 203 204 // An UnsupportedValueError is returned by [Marshal] when attempting 205 // to encode an unsupported value. 206 type UnsupportedValueError struct { 207 Value reflect.Value 208 Str string 209 } 210 211 func (e *UnsupportedValueError) Error() string { 212 return "json: unsupported value: " + e.Str 213 } 214 215 // Before Go 1.2, an InvalidUTF8Error was returned by [Marshal] when 216 // attempting to encode a string value with invalid UTF-8 sequences. 217 // As of Go 1.2, [Marshal] instead coerces the string to valid UTF-8 by 218 // replacing invalid bytes with the Unicode replacement rune U+FFFD. 219 // 220 // Deprecated: No longer used; kept for compatibility. 221 type InvalidUTF8Error struct { 222 S string // the whole string value that caused the error 223 } 224 225 func (e *InvalidUTF8Error) Error() string { 226 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) 227 } 228 229 // A MarshalerError represents an error from calling a 230 // [Marshaler.MarshalJSON] or [encoding.TextMarshaler.MarshalText] method. 231 type MarshalerError struct { 232 Type reflect.Type 233 Err error 234 sourceFunc string 235 } 236 237 func (e *MarshalerError) Error() string { 238 srcFunc := e.sourceFunc 239 if srcFunc == "" { 240 srcFunc = "MarshalJSON" 241 } 242 return "json: error calling " + srcFunc + 243 " for type " + e.Type.String() + 244 ": " + e.Err.Error() 245 } 246 247 // Unwrap returns the underlying error. 248 func (e *MarshalerError) Unwrap() error { return e.Err } 249 250 const hex = "0123456789abcdef" 251 252 // An encodeState encodes JSON into a bytes.Buffer. 253 type encodeState struct { 254 bytes.Buffer // accumulated output 255 256 // Keep track of what pointers we've seen in the current recursive call 257 // path, to avoid cycles that could lead to a stack overflow. Only do 258 // the relatively expensive map operations if ptrLevel is larger than 259 // startDetectingCyclesAfter, so that we skip the work if we're within a 260 // reasonable amount of nested pointers deep. 261 ptrLevel uint 262 ptrSeen map[any]struct{} 263 } 264 265 const startDetectingCyclesAfter = 1000 266 267 var encodeStatePool sync.Pool 268 269 func newEncodeState() *encodeState { 270 if v := encodeStatePool.Get(); v != nil { 271 e := v.(*encodeState) 272 e.Reset() 273 if len(e.ptrSeen) > 0 { 274 panic("ptrEncoder.encode should have emptied ptrSeen via defers") 275 } 276 e.ptrLevel = 0 277 return e 278 } 279 return &encodeState{ptrSeen: make(map[any]struct{})} 280 } 281 282 // jsonError is an error wrapper type for internal use only. 283 // Panics with errors are wrapped in jsonError so that the top-level recover 284 // can distinguish intentional panics from this package. 285 type jsonError struct{ error } 286 287 func (e *encodeState) marshal(v any, opts encOpts) (err error) { 288 defer func() { 289 if r := recover(); r != nil { 290 if je, ok := r.(jsonError); ok { 291 err = je.error 292 } else { 293 panic(r) 294 } 295 } 296 }() 297 e.reflectValue(reflect.ValueOf(v), opts) 298 return nil 299 } 300 301 // error aborts the encoding by panicking with err wrapped in jsonError. 302 func (e *encodeState) error(err error) { 303 panic(jsonError{err}) 304 } 305 306 func isEmptyValue(v reflect.Value) bool { 307 switch v.Kind() { 308 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 309 return v.Len() == 0 310 case reflect.Bool, 311 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 312 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 313 reflect.Float32, reflect.Float64, 314 reflect.Interface, reflect.Pointer: 315 return v.IsZero() 316 } 317 return false 318 } 319 320 func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) { 321 valueEncoder(v)(e, v, opts) 322 } 323 324 type encOpts struct { 325 // quoted causes primitive fields to be encoded inside JSON strings. 326 quoted bool 327 // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings. 328 escapeHTML bool 329 } 330 331 type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts) 332 333 var encoderCache sync.Map // map[reflect.Type]encoderFunc 334 335 func valueEncoder(v reflect.Value) encoderFunc { 336 if !v.IsValid() { 337 return invalidValueEncoder 338 } 339 return typeEncoder(v.Type()) 340 } 341 342 func typeEncoder(t reflect.Type) encoderFunc { 343 if fi, ok := encoderCache.Load(t); ok { 344 return fi.(encoderFunc) 345 } 346 347 // To deal with recursive types, populate the map with an 348 // indirect func before we build it. This type waits on the 349 // real func (f) to be ready and then calls it. This indirect 350 // func is only used for recursive types. 351 var ( 352 wg sync.WaitGroup 353 f encoderFunc 354 ) 355 wg.Add(1) 356 fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) { 357 wg.Wait() 358 f(e, v, opts) 359 })) 360 if loaded { 361 return fi.(encoderFunc) 362 } 363 364 // Compute the real encoder and replace the indirect func with it. 365 f = newTypeEncoder(t, true) 366 wg.Done() 367 encoderCache.Store(t, f) 368 return f 369 } 370 371 var ( 372 marshalerType = reflect.TypeFor[Marshaler]() 373 textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]() 374 ) 375 376 // newTypeEncoder constructs an encoderFunc for a type. 377 // The returned encoder only checks CanAddr when allowAddr is true. 378 func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { 379 // If we have a non-pointer value whose type implements 380 // Marshaler with a value receiver, then we're better off taking 381 // the address of the value - otherwise we end up with an 382 // allocation as we cast the value to an interface. 383 if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) { 384 return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) 385 } 386 if t.Implements(marshalerType) { 387 return marshalerEncoder 388 } 389 if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) { 390 return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false)) 391 } 392 if t.Implements(textMarshalerType) { 393 return textMarshalerEncoder 394 } 395 396 switch t.Kind() { 397 case reflect.Bool: 398 return boolEncoder 399 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 400 return intEncoder 401 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 402 return uintEncoder 403 case reflect.Float32: 404 return float32Encoder 405 case reflect.Float64: 406 return float64Encoder 407 case reflect.String: 408 return stringEncoder 409 case reflect.Interface: 410 return interfaceEncoder 411 case reflect.Struct: 412 return newStructEncoder(t) 413 case reflect.Map: 414 return newMapEncoder(t) 415 case reflect.Slice: 416 return newSliceEncoder(t) 417 case reflect.Array: 418 return newArrayEncoder(t) 419 case reflect.Pointer: 420 return newPtrEncoder(t) 421 default: 422 return unsupportedTypeEncoder 423 } 424 } 425 426 func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) { 427 e.WriteString("null") 428 } 429 430 func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 431 if v.Kind() == reflect.Pointer && v.IsNil() { 432 e.WriteString("null") 433 return 434 } 435 m, ok := v.Interface().(Marshaler) 436 if !ok { 437 e.WriteString("null") 438 return 439 } 440 b, err := m.MarshalJSON() 441 if err == nil { 442 e.Grow(len(b)) 443 out := e.AvailableBuffer() 444 out, err = appendCompact(out, b, opts.escapeHTML) 445 e.Buffer.Write(out) 446 } 447 if err != nil { 448 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"}) 449 } 450 } 451 452 func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 453 va := v.Addr() 454 if va.IsNil() { 455 e.WriteString("null") 456 return 457 } 458 m := va.Interface().(Marshaler) 459 b, err := m.MarshalJSON() 460 if err == nil { 461 e.Grow(len(b)) 462 out := e.AvailableBuffer() 463 out, err = appendCompact(out, b, opts.escapeHTML) 464 e.Buffer.Write(out) 465 } 466 if err != nil { 467 e.error(&MarshalerError{v.Type(), err, "MarshalJSON"}) 468 } 469 } 470 471 func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 472 if v.Kind() == reflect.Pointer && v.IsNil() { 473 e.WriteString("null") 474 return 475 } 476 m, ok := v.Interface().(encoding.TextMarshaler) 477 if !ok { 478 e.WriteString("null") 479 return 480 } 481 b, err := m.MarshalText() 482 if err != nil { 483 e.error(&MarshalerError{v.Type(), err, "MarshalText"}) 484 } 485 e.Write(appendString(e.AvailableBuffer(), b, opts.escapeHTML)) 486 } 487 488 func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { 489 va := v.Addr() 490 if va.IsNil() { 491 e.WriteString("null") 492 return 493 } 494 m := va.Interface().(encoding.TextMarshaler) 495 b, err := m.MarshalText() 496 if err != nil { 497 e.error(&MarshalerError{v.Type(), err, "MarshalText"}) 498 } 499 e.Write(appendString(e.AvailableBuffer(), b, opts.escapeHTML)) 500 } 501 502 func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) { 503 b := e.AvailableBuffer() 504 b = mayAppendQuote(b, opts.quoted) 505 b = strconv.AppendBool(b, v.Bool()) 506 b = mayAppendQuote(b, opts.quoted) 507 e.Write(b) 508 } 509 510 func intEncoder(e *encodeState, v reflect.Value, opts encOpts) { 511 b := e.AvailableBuffer() 512 b = mayAppendQuote(b, opts.quoted) 513 b = strconv.AppendInt(b, v.Int(), 10) 514 b = mayAppendQuote(b, opts.quoted) 515 e.Write(b) 516 } 517 518 func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) { 519 b := e.AvailableBuffer() 520 b = mayAppendQuote(b, opts.quoted) 521 b = strconv.AppendUint(b, v.Uint(), 10) 522 b = mayAppendQuote(b, opts.quoted) 523 e.Write(b) 524 } 525 526 type floatEncoder int // number of bits 527 528 func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 529 f := v.Float() 530 if math.IsInf(f, 0) || math.IsNaN(f) { 531 e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))}) 532 } 533 534 // Convert as if by ES6 number to string conversion. 535 // This matches most other JSON generators. 536 // See golang.org/issue/6384 and golang.org/issue/14135. 537 // Like fmt %g, but the exponent cutoffs are different 538 // and exponents themselves are not padded to two digits. 539 b := e.AvailableBuffer() 540 b = mayAppendQuote(b, opts.quoted) 541 abs := math.Abs(f) 542 fmt := byte('f') 543 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 544 if abs != 0 { 545 if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { 546 fmt = 'e' 547 } 548 } 549 b = strconv.AppendFloat(b, f, fmt, -1, int(bits)) 550 if fmt == 'e' { 551 // clean up e-09 to e-9 552 n := len(b) 553 if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' { 554 b[n-2] = b[n-1] 555 b = b[:n-1] 556 } 557 } 558 b = mayAppendQuote(b, opts.quoted) 559 e.Write(b) 560 } 561 562 var ( 563 float32Encoder = (floatEncoder(32)).encode 564 float64Encoder = (floatEncoder(64)).encode 565 ) 566 567 func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { 568 if v.Type() == numberType { 569 numStr := v.String() 570 // In Go1.5 the empty string encodes to "0", while this is not a valid number literal 571 // we keep compatibility so check validity after this. 572 if numStr == "" { 573 numStr = "0" // Number's zero-val 574 } 575 if !isValidNumber(numStr) { 576 e.error(fmt.Errorf("json: invalid number literal %q", numStr)) 577 } 578 b := e.AvailableBuffer() 579 b = mayAppendQuote(b, opts.quoted) 580 b = append(b, numStr...) 581 b = mayAppendQuote(b, opts.quoted) 582 e.Write(b) 583 return 584 } 585 if opts.quoted { 586 b := appendString(nil, v.String(), opts.escapeHTML) 587 e.Write(appendString(e.AvailableBuffer(), b, false)) // no need to escape again since it is already escaped 588 } else { 589 e.Write(appendString(e.AvailableBuffer(), v.String(), opts.escapeHTML)) 590 } 591 } 592 593 // isValidNumber reports whether s is a valid JSON number literal. 594 func isValidNumber(s string) bool { 595 // This function implements the JSON numbers grammar. 596 // See https://tools.ietf.org/html/rfc7159#section-6 597 // and https://www.json.org/img/number.png 598 599 if s == "" { 600 return false 601 } 602 603 // Optional - 604 if s[0] == '-' { 605 s = s[1:] 606 if s == "" { 607 return false 608 } 609 } 610 611 // Digits 612 switch { 613 default: 614 return false 615 616 case s[0] == '0': 617 s = s[1:] 618 619 case '1' <= s[0] && s[0] <= '9': 620 s = s[1:] 621 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { 622 s = s[1:] 623 } 624 } 625 626 // . followed by 1 or more digits. 627 if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { 628 s = s[2:] 629 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { 630 s = s[1:] 631 } 632 } 633 634 // e or E followed by an optional - or + and 635 // 1 or more digits. 636 if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { 637 s = s[1:] 638 if s[0] == '+' || s[0] == '-' { 639 s = s[1:] 640 if s == "" { 641 return false 642 } 643 } 644 for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { 645 s = s[1:] 646 } 647 } 648 649 // Make sure we are at the end. 650 return s == "" 651 } 652 653 func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { 654 if v.IsNil() { 655 e.WriteString("null") 656 return 657 } 658 e.reflectValue(v.Elem(), opts) 659 } 660 661 func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) { 662 e.error(&UnsupportedTypeError{v.Type()}) 663 } 664 665 type structEncoder struct { 666 fields structFields 667 } 668 669 type structFields struct { 670 list []field 671 byExactName map[string]*field 672 byFoldedName map[string]*field 673 } 674 675 func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 676 next := byte('{') 677 FieldLoop: 678 for i := range se.fields.list { 679 f := &se.fields.list[i] 680 681 // Find the nested struct field by following f.index. 682 fv := v 683 for _, i := range f.index { 684 if fv.Kind() == reflect.Pointer { 685 if fv.IsNil() { 686 continue FieldLoop 687 } 688 fv = fv.Elem() 689 } 690 fv = fv.Field(i) 691 } 692 693 if f.omitEmpty && isEmptyValue(fv) { 694 continue 695 } 696 e.WriteByte(next) 697 next = ',' 698 if opts.escapeHTML { 699 e.WriteString(f.nameEscHTML) 700 } else { 701 e.WriteString(f.nameNonEsc) 702 } 703 opts.quoted = f.quoted 704 f.encoder(e, fv, opts) 705 } 706 if next == '{' { 707 e.WriteString("{}") 708 } else { 709 e.WriteByte('}') 710 } 711 } 712 713 func newStructEncoder(t reflect.Type) encoderFunc { 714 se := structEncoder{fields: cachedTypeFields(t)} 715 return se.encode 716 } 717 718 type mapEncoder struct { 719 elemEnc encoderFunc 720 } 721 722 func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 723 if v.IsNil() { 724 e.WriteString("null") 725 return 726 } 727 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { 728 // We're a large number of nested ptrEncoder.encode calls deep; 729 // start checking if we've run into a pointer cycle. 730 ptr := v.UnsafePointer() 731 if _, ok := e.ptrSeen[ptr]; ok { 732 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) 733 } 734 e.ptrSeen[ptr] = struct{}{} 735 defer delete(e.ptrSeen, ptr) 736 } 737 e.WriteByte('{') 738 739 // Extract and sort the keys. 740 var ( 741 sv = make([]reflectWithString, v.Len()) 742 mi = v.MapRange() 743 err error 744 ) 745 for i := 0; mi.Next(); i++ { 746 if sv[i].ks, err = resolveKeyName(mi.Key()); err != nil { 747 e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error())) 748 } 749 sv[i].v = mi.Value() 750 } 751 slices.SortFunc(sv, func(i, j reflectWithString) int { 752 return strings.Compare(i.ks, j.ks) 753 }) 754 755 for i, kv := range sv { 756 if i > 0 { 757 e.WriteByte(',') 758 } 759 e.Write(appendString(e.AvailableBuffer(), kv.ks, opts.escapeHTML)) 760 e.WriteByte(':') 761 me.elemEnc(e, kv.v, opts) 762 } 763 e.WriteByte('}') 764 e.ptrLevel-- 765 } 766 767 func newMapEncoder(t reflect.Type) encoderFunc { 768 switch t.Key().Kind() { 769 case reflect.String, 770 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 771 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 772 default: 773 if !t.Key().Implements(textMarshalerType) { 774 return unsupportedTypeEncoder 775 } 776 } 777 me := mapEncoder{typeEncoder(t.Elem())} 778 return me.encode 779 } 780 781 func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) { 782 if v.IsNil() { 783 e.WriteString("null") 784 return 785 } 786 787 s := v.Bytes() 788 b := e.AvailableBuffer() 789 b = append(b, '"') 790 b = base64.StdEncoding.AppendEncode(b, s) 791 b = append(b, '"') 792 e.Write(b) 793 } 794 795 // sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil. 796 type sliceEncoder struct { 797 arrayEnc encoderFunc 798 } 799 800 func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 801 if v.IsNil() { 802 e.WriteString("null") 803 return 804 } 805 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { 806 // We're a large number of nested ptrEncoder.encode calls deep; 807 // start checking if we've run into a pointer cycle. 808 // Here we use a struct to memorize the pointer to the first element of the slice 809 // and its length. 810 ptr := struct { 811 ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe 812 len int 813 }{v.UnsafePointer(), v.Len()} 814 if _, ok := e.ptrSeen[ptr]; ok { 815 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) 816 } 817 e.ptrSeen[ptr] = struct{}{} 818 defer delete(e.ptrSeen, ptr) 819 } 820 se.arrayEnc(e, v, opts) 821 e.ptrLevel-- 822 } 823 824 func newSliceEncoder(t reflect.Type) encoderFunc { 825 // Byte slices get special treatment; arrays don't. 826 if t.Elem().Kind() == reflect.Uint8 { 827 p := reflect.PointerTo(t.Elem()) 828 if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) { 829 return encodeByteSlice 830 } 831 } 832 enc := sliceEncoder{newArrayEncoder(t)} 833 return enc.encode 834 } 835 836 type arrayEncoder struct { 837 elemEnc encoderFunc 838 } 839 840 func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 841 e.WriteByte('[') 842 n := v.Len() 843 for i := 0; i < n; i++ { 844 if i > 0 { 845 e.WriteByte(',') 846 } 847 ae.elemEnc(e, v.Index(i), opts) 848 } 849 e.WriteByte(']') 850 } 851 852 func newArrayEncoder(t reflect.Type) encoderFunc { 853 enc := arrayEncoder{typeEncoder(t.Elem())} 854 return enc.encode 855 } 856 857 type ptrEncoder struct { 858 elemEnc encoderFunc 859 } 860 861 func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 862 if v.IsNil() { 863 e.WriteString("null") 864 return 865 } 866 if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { 867 // We're a large number of nested ptrEncoder.encode calls deep; 868 // start checking if we've run into a pointer cycle. 869 ptr := v.Interface() 870 if _, ok := e.ptrSeen[ptr]; ok { 871 e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) 872 } 873 e.ptrSeen[ptr] = struct{}{} 874 defer delete(e.ptrSeen, ptr) 875 } 876 pe.elemEnc(e, v.Elem(), opts) 877 e.ptrLevel-- 878 } 879 880 func newPtrEncoder(t reflect.Type) encoderFunc { 881 enc := ptrEncoder{typeEncoder(t.Elem())} 882 return enc.encode 883 } 884 885 type condAddrEncoder struct { 886 canAddrEnc, elseEnc encoderFunc 887 } 888 889 func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { 890 if v.CanAddr() { 891 ce.canAddrEnc(e, v, opts) 892 } else { 893 ce.elseEnc(e, v, opts) 894 } 895 } 896 897 // newCondAddrEncoder returns an encoder that checks whether its value 898 // CanAddr and delegates to canAddrEnc if so, else to elseEnc. 899 func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { 900 enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} 901 return enc.encode 902 } 903 904 func isValidTag(s string) bool { 905 if s == "" { 906 return false 907 } 908 for _, c := range s { 909 switch { 910 case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c): 911 // Backslash and quote chars are reserved, but 912 // otherwise any punctuation chars are allowed 913 // in a tag name. 914 case !unicode.IsLetter(c) && !unicode.IsDigit(c): 915 return false 916 } 917 } 918 return true 919 } 920 921 func typeByIndex(t reflect.Type, index []int) reflect.Type { 922 for _, i := range index { 923 if t.Kind() == reflect.Pointer { 924 t = t.Elem() 925 } 926 t = t.Field(i).Type 927 } 928 return t 929 } 930 931 type reflectWithString struct { 932 v reflect.Value 933 ks string 934 } 935 936 func resolveKeyName(k reflect.Value) (string, error) { 937 if k.Kind() == reflect.String { 938 return k.String(), nil 939 } 940 if tm, ok := k.Interface().(encoding.TextMarshaler); ok { 941 if k.Kind() == reflect.Pointer && k.IsNil() { 942 return "", nil 943 } 944 buf, err := tm.MarshalText() 945 return string(buf), err 946 } 947 switch k.Kind() { 948 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 949 return strconv.FormatInt(k.Int(), 10), nil 950 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 951 return strconv.FormatUint(k.Uint(), 10), nil 952 } 953 panic("unexpected map key type") 954 } 955 956 func appendString[Bytes []byte | string](dst []byte, src Bytes, escapeHTML bool) []byte { 957 dst = append(dst, '"') 958 start := 0 959 for i := 0; i < len(src); { 960 if b := src[i]; b < utf8.RuneSelf { 961 if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { 962 i++ 963 continue 964 } 965 dst = append(dst, src[start:i]...) 966 switch b { 967 case '\\', '"': 968 dst = append(dst, '\\', b) 969 case '\b': 970 dst = append(dst, '\\', 'b') 971 case '\f': 972 dst = append(dst, '\\', 'f') 973 case '\n': 974 dst = append(dst, '\\', 'n') 975 case '\r': 976 dst = append(dst, '\\', 'r') 977 case '\t': 978 dst = append(dst, '\\', 't') 979 default: 980 // This encodes bytes < 0x20 except for \b, \f, \n, \r and \t. 981 // If escapeHTML is set, it also escapes <, >, and & 982 // because they can lead to security holes when 983 // user-controlled strings are rendered into JSON 984 // and served to some browsers. 985 dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF]) 986 } 987 i++ 988 start = i 989 continue 990 } 991 // TODO(https://go.dev/issue/56948): Use generic utf8 functionality. 992 // For now, cast only a small portion of byte slices to a string 993 // so that it can be stack allocated. This slows down []byte slightly 994 // due to the extra copy, but keeps string performance roughly the same. 995 n := len(src) - i 996 if n > utf8.UTFMax { 997 n = utf8.UTFMax 998 } 999 c, size := utf8.DecodeRuneInString(string(src[i : i+n])) 1000 if c == utf8.RuneError && size == 1 { 1001 dst = append(dst, src[start:i]...) 1002 dst = append(dst, `\ufffd`...) 1003 i += size 1004 start = i 1005 continue 1006 } 1007 // U+2028 is LINE SEPARATOR. 1008 // U+2029 is PARAGRAPH SEPARATOR. 1009 // They are both technically valid characters in JSON strings, 1010 // but don't work in JSONP, which has to be evaluated as JavaScript, 1011 // and can lead to security holes there. It is valid JSON to 1012 // escape them, so we do so unconditionally. 1013 // See https://en.wikipedia.org/wiki/JSON#Safety. 1014 if c == '\u2028' || c == '\u2029' { 1015 dst = append(dst, src[start:i]...) 1016 dst = append(dst, '\\', 'u', '2', '0', '2', hex[c&0xF]) 1017 i += size 1018 start = i 1019 continue 1020 } 1021 i += size 1022 } 1023 dst = append(dst, src[start:]...) 1024 dst = append(dst, '"') 1025 return dst 1026 } 1027 1028 // A field represents a single field found in a struct. 1029 type field struct { 1030 name string 1031 nameBytes []byte // []byte(name) 1032 1033 nameNonEsc string // `"` + name + `":` 1034 nameEscHTML string // `"` + HTMLEscape(name) + `":` 1035 1036 tag bool 1037 index []int 1038 typ reflect.Type 1039 omitEmpty bool 1040 quoted bool 1041 1042 encoder encoderFunc 1043 } 1044 1045 // byIndex sorts field by index sequence. 1046 type byIndex []field 1047 1048 func (x byIndex) Len() int { return len(x) } 1049 1050 func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 1051 1052 func (x byIndex) Less(i, j int) bool { 1053 for k, xik := range x[i].index { 1054 if k >= len(x[j].index) { 1055 return false 1056 } 1057 if xik != x[j].index[k] { 1058 return xik < x[j].index[k] 1059 } 1060 } 1061 return len(x[i].index) < len(x[j].index) 1062 } 1063 1064 // typeFields returns a list of fields that JSON should recognize for the given type. 1065 // The algorithm is breadth-first search over the set of structs to include - the top struct 1066 // and then any reachable anonymous structs. 1067 func typeFields(t reflect.Type) structFields { 1068 // Anonymous fields to explore at the current level and the next. 1069 current := []field{} 1070 next := []field{{typ: t}} 1071 1072 // Count of queued names for current level and the next. 1073 var count, nextCount map[reflect.Type]int 1074 1075 // Types already visited at an earlier level. 1076 visited := map[reflect.Type]bool{} 1077 1078 // Fields found. 1079 var fields []field 1080 1081 // Buffer to run appendHTMLEscape on field names. 1082 var nameEscBuf []byte 1083 1084 for len(next) > 0 { 1085 current, next = next, current[:0] 1086 count, nextCount = nextCount, map[reflect.Type]int{} 1087 1088 for _, f := range current { 1089 if visited[f.typ] { 1090 continue 1091 } 1092 visited[f.typ] = true 1093 1094 // Scan f.typ for fields to include. 1095 for i := 0; i < f.typ.NumField(); i++ { 1096 sf := f.typ.Field(i) 1097 if sf.Anonymous { 1098 t := sf.Type 1099 if t.Kind() == reflect.Pointer { 1100 t = t.Elem() 1101 } 1102 if !sf.IsExported() && t.Kind() != reflect.Struct { 1103 // Ignore embedded fields of unexported non-struct types. 1104 continue 1105 } 1106 // Do not ignore embedded fields of unexported struct types 1107 // since they may have exported fields. 1108 } else if !sf.IsExported() { 1109 // Ignore unexported non-embedded fields. 1110 continue 1111 } 1112 tag := sf.Tag.Get("json") 1113 if tag == "-" { 1114 continue 1115 } 1116 name, opts := parseTag(tag) 1117 if !isValidTag(name) { 1118 name = "" 1119 } 1120 index := make([]int, len(f.index)+1) 1121 copy(index, f.index) 1122 index[len(f.index)] = i 1123 1124 ft := sf.Type 1125 if ft.Name() == "" && ft.Kind() == reflect.Pointer { 1126 // Follow pointer. 1127 ft = ft.Elem() 1128 } 1129 1130 // Only strings, floats, integers, and booleans can be quoted. 1131 quoted := false 1132 if opts.Contains("string") { 1133 switch ft.Kind() { 1134 case reflect.Bool, 1135 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1136 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 1137 reflect.Float32, reflect.Float64, 1138 reflect.String: 1139 quoted = true 1140 } 1141 } 1142 1143 // Record found field and index sequence. 1144 if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { 1145 tagged := name != "" 1146 if name == "" { 1147 name = sf.Name 1148 } 1149 field := field{ 1150 name: name, 1151 tag: tagged, 1152 index: index, 1153 typ: ft, 1154 omitEmpty: opts.Contains("omitempty"), 1155 quoted: quoted, 1156 } 1157 field.nameBytes = []byte(field.name) 1158 1159 // Build nameEscHTML and nameNonEsc ahead of time. 1160 nameEscBuf = appendHTMLEscape(nameEscBuf[:0], field.nameBytes) 1161 field.nameEscHTML = `"` + string(nameEscBuf) + `":` 1162 field.nameNonEsc = `"` + field.name + `":` 1163 1164 fields = append(fields, field) 1165 if count[f.typ] > 1 { 1166 // If there were multiple instances, add a second, 1167 // so that the annihilation code will see a duplicate. 1168 // It only cares about the distinction between 1 and 2, 1169 // so don't bother generating any more copies. 1170 fields = append(fields, fields[len(fields)-1]) 1171 } 1172 continue 1173 } 1174 1175 // Record new anonymous struct to explore in next round. 1176 nextCount[ft]++ 1177 if nextCount[ft] == 1 { 1178 next = append(next, field{name: ft.Name(), index: index, typ: ft}) 1179 } 1180 } 1181 } 1182 } 1183 1184 sort.Slice(fields, func(i, j int) bool { 1185 x := fields 1186 // sort field by name, breaking ties with depth, then 1187 // breaking ties with "name came from json tag", then 1188 // breaking ties with index sequence. 1189 if x[i].name != x[j].name { 1190 return x[i].name < x[j].name 1191 } 1192 if len(x[i].index) != len(x[j].index) { 1193 return len(x[i].index) < len(x[j].index) 1194 } 1195 if x[i].tag != x[j].tag { 1196 return x[i].tag 1197 } 1198 return byIndex(x).Less(i, j) 1199 }) 1200 1201 // Delete all fields that are hidden by the Go rules for embedded fields, 1202 // except that fields with JSON tags are promoted. 1203 1204 // The fields are sorted in primary order of name, secondary order 1205 // of field index length. Loop over names; for each name, delete 1206 // hidden fields by choosing the one dominant field that survives. 1207 out := fields[:0] 1208 for advance, i := 0, 0; i < len(fields); i += advance { 1209 // One iteration per name. 1210 // Find the sequence of fields with the name of this first field. 1211 fi := fields[i] 1212 name := fi.name 1213 for advance = 1; i+advance < len(fields); advance++ { 1214 fj := fields[i+advance] 1215 if fj.name != name { 1216 break 1217 } 1218 } 1219 if advance == 1 { // Only one field with this name 1220 out = append(out, fi) 1221 continue 1222 } 1223 dominant, ok := dominantField(fields[i : i+advance]) 1224 if ok { 1225 out = append(out, dominant) 1226 } 1227 } 1228 1229 fields = out 1230 sort.Sort(byIndex(fields)) 1231 1232 for i := range fields { 1233 f := &fields[i] 1234 f.encoder = typeEncoder(typeByIndex(t, f.index)) 1235 } 1236 exactNameIndex := make(map[string]*field, len(fields)) 1237 foldedNameIndex := make(map[string]*field, len(fields)) 1238 for i, field := range fields { 1239 exactNameIndex[field.name] = &fields[i] 1240 // For historical reasons, first folded match takes precedence. 1241 if _, ok := foldedNameIndex[string(foldName(field.nameBytes))]; !ok { 1242 foldedNameIndex[string(foldName(field.nameBytes))] = &fields[i] 1243 } 1244 } 1245 return structFields{fields, exactNameIndex, foldedNameIndex} 1246 } 1247 1248 // dominantField looks through the fields, all of which are known to 1249 // have the same name, to find the single field that dominates the 1250 // others using Go's embedding rules, modified by the presence of 1251 // JSON tags. If there are multiple top-level fields, the boolean 1252 // will be false: This condition is an error in Go and we skip all 1253 // the fields. 1254 func dominantField(fields []field) (field, bool) { 1255 // The fields are sorted in increasing index-length order, then by presence of tag. 1256 // That means that the first field is the dominant one. We need only check 1257 // for error cases: two fields at top level, either both tagged or neither tagged. 1258 if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag { 1259 return field{}, false 1260 } 1261 return fields[0], true 1262 } 1263 1264 var fieldCache sync.Map // map[reflect.Type]structFields 1265 1266 // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 1267 func cachedTypeFields(t reflect.Type) structFields { 1268 if f, ok := fieldCache.Load(t); ok { 1269 return f.(structFields) 1270 } 1271 f, _ := fieldCache.LoadOrStore(t, typeFields(t)) 1272 return f.(structFields) 1273 } 1274 1275 func mayAppendQuote(b []byte, quoted bool) []byte { 1276 if quoted { 1277 b = append(b, '"') 1278 } 1279 return b 1280 }