// 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 // // The JSON standard (RFC 7159) is lax in its definition of a number of parser // behaviors. As such, many JSON parsers behave differently in various // scenarios. These differences in parsers mean that systems that use multiple // independent JSON parser implementations may parse the same JSON object in // differing ways. // // Systems that rely on a JSON object being parsed consistently for security // purposes should be careful to understand the behaviors of this parser, as // well as how these behaviors may cause interoperability issues with other // parser implementations. // // Due to the Go Backwards Compatibility promise (https://go.dev/doc/go1compat) // there are a number of behaviors this package exhibits that may cause // interopability issues, but cannot be changed. In particular the following // parsing behaviors may cause issues: // // - If a JSON object contains duplicate keys, keys are processed in the order // they are observed, meaning later values will replace or be merged into // prior values, depending on the field type (in particular maps and structs // will have values merged, while other types have values replaced). // - When parsing a JSON object into a Go struct, keys are considered in a // case-insensitive fashion. // - When parsing a JSON object into a Go struct, unknown keys in the JSON // object are ignored (unless a [Decoder] is used and // [Decoder.DisallowUnknownFields] has been called). // - Invalid UTF-8 bytes in JSON strings are replaced by the Unicode // replacement character. // - Large JSON number integers will lose precision when unmarshaled into // floating-point types. package json import ( "bytes" "cmp" "encoding" "encoding/base64" "fmt" "math" "reflect" "slices" "strconv" "strings" "sync" "unicode" "unicode/utf8" _ "unsafe" // for linkname ) // 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