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