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