json package - encoding/json - Go Packages (original) (raw)
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 andDecoder.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.
//go:build !goexperiment.jsonv2
package main
import ( "encoding/json" "fmt" "log" "strings" )
type Animal int
const ( Unknown Animal = iota Gopher Zebra )
func (a *Animal) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } switch strings.ToLower(s) { default: *a = Unknown case "gopher": *a = Gopher case "zebra": *a = Zebra }
return nil}
func (a Animal) MarshalJSON() ([]byte, error) { var s string switch a { default: s = "unknown" case Gopher: s = "gopher" case Zebra: s = "zebra" }
return json.Marshal(s)}
func main() {
blob := ["gopher","armadillo","zebra","unknown","gopher","bee","gopher","zebra"]
var zoo []Animal
if err := json.Unmarshal([]byte(blob), &zoo); err != nil {
log.Fatal(err)
}
census := make(map[Animal]int)
for _, animal := range zoo {
census[animal] += 1
}
fmt.Printf("Zoo Census:\n* Gophers: %d\n* Zebras: %d\n* Unknown: %d\n",
census[Gopher], census[Zebra], census[Unknown])}
Output:
Zoo Census:
- Gophers: 3
- Zebras: 2
- Unknown: 3
//go:build !goexperiment.jsonv2
package main
import ( "encoding/json" "fmt" "log" "strings" )
type Size int
const ( Unrecognized Size = iota Small Large )
func (s *Size) UnmarshalText(text []byte) error { switch strings.ToLower(string(text)) { default: *s = Unrecognized case "small": *s = Small case "large": *s = Large } return nil }
func (s Size) MarshalText() ([]byte, error) { var name string switch s { default: name = "unrecognized" case Small: name = "small" case Large: name = "large" } return []byte(name), nil }
func main() {
blob := ["small","regular","large","unrecognized","small","normal","small","large"]
var inventory []Size
if err := json.Unmarshal([]byte(blob), &inventory); err != nil {
log.Fatal(err)
}
counts := make(map[Size]int)
for _, size := range inventory {
counts[size] += 1
}
fmt.Printf("Inventory Counts:\n* Small: %d\n* Large: %d\n* Unrecognized: %d\n",
counts[Small], counts[Large], counts[Unrecognized])}
Output:
Inventory Counts:
Small: 3
Large: 2
Unrecognized: 3
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
func MarshalIndent(v any, prefix, indent string) ([]byte, error)
type InvalidUTF8Errordeprecated
type UnmarshalFieldErrordeprecated
This section is empty.
This section is empty.
Compact appends to dst the JSON-encoded src with insignificant space characters elided.
HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 so that the JSON will be safe to embed inside HTML