| // Copyright 2010 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| //go:build goexperiment.jsonv2 | |
| // Package json implements encoding and decoding of JSON as defined in | |
| // RFC 7159. The mapping between JSON and Go values is described | |
| // in the documentation for the Marshal and Unmarshal functions. | |
| // | |
| // See "JSON and Go" for an introduction to this package: | |
| // https://golang.org/doc/articles/json_and_go.html | |
| // | |
| // # Security Considerations | |
| // | |
| // See the "Security Considerations" section in [encoding/json/v2]. | |
| // | |
| // For historical reasons, the default behavior of v1 [encoding/json] | |
| // unfortunately operates with less secure defaults. | |
| // New usages of JSON in Go are encouraged to use [encoding/json/v2] instead. | |
| package json | |
| import ( | |
| "reflect" | |
| "strconv" | |
| jsonv2 "encoding/json/v2" | |
| ) | |
| // Marshal returns the JSON encoding of v. | |
| // | |
| // Marshal traverses the value v recursively. | |
| // If an encountered value implements [Marshaler] | |
| // and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] | |
| // to produce JSON. If no [Marshaler.MarshalJSON] method is present but the | |
| // value implements [encoding.TextMarshaler] instead, Marshal calls | |
| // [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. | |
| // The nil pointer exception is not strictly necessary | |
| // but mimics a similar, necessary exception in the behavior of | |
| // [Unmarshaler.UnmarshalJSON]. | |
| // | |
| // Otherwise, Marshal uses the following type-dependent default encodings: | |
| // | |
| // Boolean values encode as JSON booleans. | |
| // | |
| // Floating point, integer, and [Number] values encode as JSON numbers. | |
| // NaN and +/-Inf values will return an [UnsupportedValueError]. | |
| // | |
| // String values encode as JSON strings coerced to valid UTF-8, | |
| // replacing invalid bytes with the Unicode replacement rune. | |
| // So that the JSON will be safe to embed inside HTML <script> tags, | |
| // the string is encoded using [HTMLEscape], | |
| // which replaces "<", ">", "&", U+2028, and U+2029 are escaped | |
| // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". | |
| // This replacement can be disabled when using an [Encoder], | |
| // by calling [Encoder.SetEscapeHTML](false). | |
| // | |
| // Array and slice values encode as JSON arrays, except that | |
| // []byte encodes as a base64-encoded string, and a nil slice | |
| // encodes as the null JSON value. | |
| // | |
| // Struct values encode as JSON objects. | |
| // Each exported struct field becomes a member of the object, using the | |
| // field name as the object key, unless the field is omitted for one of the | |
| // reasons given below. | |
| // | |
| // The encoding of each struct field can be customized by the format string | |
| // stored under the "json" key in the struct field's tag. | |
| // The format string gives the name of the field, possibly followed by a | |
| // comma-separated list of options. The name may be empty in order to | |
| // specify options without overriding the default field name. | |
| // | |
| // The "omitempty" option specifies that the field should be omitted | |
| // from the encoding if the field has an empty value, defined as | |
| // false, 0, a nil pointer, a nil interface value, and any array, | |
| // slice, map, or string of length zero. | |
| // | |
| // As a special case, if the field tag is "-", the field is always omitted. | |
| // JSON names containing commas or quotes, or names identical to "" or "-", | |
| // can be specified using a single-quoted string literal, where the syntax | |
| // is identical to the Go grammar for a double-quoted string literal, | |
| // but instead uses single quotes as the delimiters. | |
| // | |
| // Examples of struct field tags and their meanings: | |
| // | |
| // // Field appears in JSON as key "myName". | |
| // Field int `json:"myName"` | |
| // | |
| // // Field appears in JSON as key "myName" and | |
| // // the field is omitted from the object if its value is empty, | |
| // // as defined above. | |
| // Field int `json:"myName,omitempty"` | |
| // | |
| // // Field appears in JSON as key "Field" (the default), but | |
| // // the field is skipped if empty. | |
| // // Note the leading comma. | |
| // Field int `json:",omitempty"` | |
| // | |
| // // Field is ignored by this package. | |
| // Field int `json:"-"` | |
| // | |
| // // Field appears in JSON as key "-". | |
| // Field int `json:"'-'"` | |
| // | |
| // The "omitzero" option specifies that the field should be omitted | |
| // from the encoding if the field has a zero value, according to rules: | |
| // | |
| // 1) If the field type has an "IsZero() bool" method, that will be used to | |
| // determine whether the value is zero. | |
| // | |
| // 2) Otherwise, the value is zero if it is the zero value for its type. | |
| // | |
| // If both "omitempty" and "omitzero" are specified, the field will be omitted | |
| // if the value is either empty or zero (or both). | |
| // | |
| // The "string" option signals that a field is stored as JSON inside a | |
| // JSON-encoded string. It applies only to fields of string, floating point, | |
| // integer, or boolean types. This extra level of encoding is sometimes used | |
| // when communicating with JavaScript programs: | |
| // | |
| // Int64String int64 `json:",string"` | |
| // | |
| // The key name will be used if it's a non-empty string consisting of | |
| // only Unicode letters, digits, and ASCII punctuation except quotation | |
| // marks, backslash, and comma. | |
| // | |
| // Embedded struct fields are usually marshaled as if their inner exported fields | |
| // were fields in the outer struct, subject to the usual Go visibility rules amended | |
| // as described in the next paragraph. | |
| // An anonymous struct field with a name given in its JSON tag is treated as | |
| // having that name, rather than being anonymous. | |
| // An anonymous struct field of interface type is treated the same as having | |
| // that type as its name, rather than being anonymous. | |
| // | |
| // The Go visibility rules for struct fields are amended for JSON when | |
| // deciding which field to marshal or unmarshal. If there are | |
| // multiple fields at the same level, and that level is the least | |
| // nested (and would therefore be the nesting level selected by the | |
| // usual Go rules), the following extra rules apply: | |
| // | |
| // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, | |
| // even if there are multiple untagged fields that would otherwise conflict. | |
| // | |
| // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. | |
| // | |
| // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. | |
| // | |
| // Handling of anonymous struct fields is new in Go 1.1. | |
| // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of | |
| // an anonymous struct field in both current and earlier versions, give the field | |
| // a JSON tag of "-". | |
| // | |
| // Map values encode as JSON objects. The map's key type must either be a | |
| // string, an integer type, or implement [encoding.TextMarshaler]. The map keys | |
| // are sorted and used as JSON object keys by applying the following rules, | |
| // subject to the UTF-8 coercion described for string values above: | |
| // - keys of any string type are used directly | |
| // - keys that implement [encoding.TextMarshaler] are marshaled | |
| // - integer keys are converted to strings | |
| // | |
| // Pointer values encode as the value pointed to. | |
| // A nil pointer encodes as the null JSON value. | |
| // | |
| // Interface values encode as the value contained in the interface. | |
| // A nil interface value encodes as the null JSON value. | |
| // | |
| // Channel, complex, and function values cannot be encoded in JSON. | |
| // Attempting to encode such a value causes Marshal to return | |
| // an [UnsupportedTypeError]. | |
| // | |
| // JSON cannot represent cyclic data structures and Marshal does not | |
| // handle them. Passing cyclic structures to Marshal will result in | |
| // an error. | |
| func Marshal(v any) ([]byte, error) { | |
| return jsonv2.Marshal(v, DefaultOptionsV1()) | |
| } | |
| // MarshalIndent is like [Marshal] but applies [Indent] to format the output. | |
| // Each JSON element in the output will begin on a new line beginning with prefix | |
| // followed by one or more copies of indent according to the indentation nesting. | |
| func MarshalIndent(v any, prefix, indent string) ([]byte, error) { | |
| b, err := Marshal(v) | |
| if err != nil { | |
| return nil, err | |
| } | |
| b, err = appendIndent(nil, b, prefix, indent) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return b, nil | |
| } | |
| // Marshaler is the interface implemented by types that | |
| // can marshal themselves into valid JSON. | |
| type Marshaler = jsonv2.Marshaler | |
| // An UnsupportedTypeError is returned by [Marshal] when attempting | |
| // to encode an unsupported value type. | |
| type UnsupportedTypeError struct { | |
| Type reflect.Type | |
| } | |
| func (e *UnsupportedTypeError) Error() string { | |
| return "json: unsupported type: " + e.Type.String() | |
| } | |
| // An UnsupportedValueError is returned by [Marshal] when attempting | |
| // to encode an unsupported value. | |
| type UnsupportedValueError struct { | |
| Value reflect.Value | |
| Str string | |
| } | |
| func (e *UnsupportedValueError) Error() string { | |
| return "json: unsupported value: " + e.Str | |
| } | |
| // Before Go 1.2, an InvalidUTF8Error was returned by [Marshal] when | |
| // attempting to encode a string value with invalid UTF-8 sequences. | |
| // As of Go 1.2, [Marshal] instead coerces the string to valid UTF-8 by | |
| // replacing invalid bytes with the Unicode replacement rune U+FFFD. | |
| // | |
| // Deprecated: No longer used; kept for compatibility. | |
| type InvalidUTF8Error struct { | |
| S string // the whole string value that caused the error | |
| } | |
| func (e *InvalidUTF8Error) Error() string { | |
| return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) | |
| } | |
| // A MarshalerError represents an error from calling a | |
| // [Marshaler.MarshalJSON] or [encoding.TextMarshaler.MarshalText] method. | |
| type MarshalerError struct { | |
| Type reflect.Type | |
| Err error | |
| sourceFunc string | |
| } | |
| func (e *MarshalerError) Error() string { | |
| srcFunc := e.sourceFunc | |
| if srcFunc == "" { | |
| srcFunc = "MarshalJSON" | |
| } | |
| return "json: error calling " + srcFunc + | |
| " for type " + e.Type.String() + | |
| ": " + e.Err.Error() | |
| } | |
| // Unwrap returns the underlying error. | |
| func (e *MarshalerError) Unwrap() error { return e.Err } | |