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