Source file src/encoding/json/v2/arshal_default.go

     1  // Copyright 2020 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
     8  
     9  import (
    10  	"bytes"
    11  	"cmp"
    12  	"encoding"
    13  	"encoding/base32"
    14  	"encoding/base64"
    15  	"encoding/hex"
    16  	"errors"
    17  	"fmt"
    18  	"math"
    19  	"reflect"
    20  	"slices"
    21  	"strconv"
    22  	"strings"
    23  	"sync"
    24  
    25  	"encoding/json/internal"
    26  	"encoding/json/internal/jsonflags"
    27  	"encoding/json/internal/jsonopts"
    28  	"encoding/json/internal/jsonwire"
    29  	"encoding/json/jsontext"
    30  )
    31  
    32  // optimizeCommon specifies whether to use optimizations targeted for certain
    33  // common patterns, rather than using the slower, but more general logic.
    34  // All tests should pass regardless of whether this is true or not.
    35  const optimizeCommon = true
    36  
    37  var (
    38  	// Most natural Go types that correspond with each JSON type.
    39  	anyType          = reflect.TypeFor[any]()            // JSON value
    40  	boolType         = reflect.TypeFor[bool]()           // JSON bool
    41  	stringType       = reflect.TypeFor[string]()         // JSON string
    42  	float64Type      = reflect.TypeFor[float64]()        // JSON number
    43  	mapStringAnyType = reflect.TypeFor[map[string]any]() // JSON object
    44  	sliceAnyType     = reflect.TypeFor[[]any]()          // JSON array
    45  
    46  	bytesType       = reflect.TypeFor[[]byte]()
    47  	emptyStructType = reflect.TypeFor[struct{}]()
    48  )
    49  
    50  const startDetectingCyclesAfter = 1000
    51  
    52  type seenPointers = map[any]struct{}
    53  
    54  type typedPointer struct {
    55  	typ reflect.Type
    56  	ptr any // always stores unsafe.Pointer, but avoids depending on unsafe
    57  	len int // remember slice length to avoid false positives
    58  }
    59  
    60  // visitPointer visits pointer p of type t, reporting an error if seen before.
    61  // If successfully visited, then the caller must eventually call leave.
    62  func visitPointer(m *seenPointers, v reflect.Value) error {
    63  	p := typedPointer{v.Type(), v.UnsafePointer(), sliceLen(v)}
    64  	if _, ok := (*m)[p]; ok {
    65  		return internal.ErrCycle
    66  	}
    67  	if *m == nil {
    68  		*m = make(seenPointers)
    69  	}
    70  	(*m)[p] = struct{}{}
    71  	return nil
    72  }
    73  func leavePointer(m *seenPointers, v reflect.Value) {
    74  	p := typedPointer{v.Type(), v.UnsafePointer(), sliceLen(v)}
    75  	delete(*m, p)
    76  }
    77  
    78  func sliceLen(v reflect.Value) int {
    79  	if v.Kind() == reflect.Slice {
    80  		return v.Len()
    81  	}
    82  	return 0
    83  }
    84  
    85  func len64[Bytes ~[]byte | ~string](in Bytes) int64 {
    86  	return int64(len(in))
    87  }
    88  
    89  func makeDefaultArshaler(t reflect.Type) *arshaler {
    90  	switch t.Kind() {
    91  	case reflect.Bool:
    92  		return makeBoolArshaler(t)
    93  	case reflect.String:
    94  		return makeStringArshaler(t)
    95  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    96  		return makeIntArshaler(t)
    97  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    98  		return makeUintArshaler(t)
    99  	case reflect.Float32, reflect.Float64:
   100  		return makeFloatArshaler(t)
   101  	case reflect.Map:
   102  		return makeMapArshaler(t)
   103  	case reflect.Struct:
   104  		return makeStructArshaler(t)
   105  	case reflect.Slice:
   106  		fncs := makeSliceArshaler(t)
   107  		if t.Elem().Kind() == reflect.Uint8 {
   108  			return makeBytesArshaler(t, fncs)
   109  		}
   110  		return fncs
   111  	case reflect.Array:
   112  		fncs := makeArrayArshaler(t)
   113  		if t.Elem().Kind() == reflect.Uint8 {
   114  			return makeBytesArshaler(t, fncs)
   115  		}
   116  		return fncs
   117  	case reflect.Pointer:
   118  		return makePointerArshaler(t)
   119  	case reflect.Interface:
   120  		return makeInterfaceArshaler(t)
   121  	default:
   122  		return makeInvalidArshaler(t)
   123  	}
   124  }
   125  
   126  func makeBoolArshaler(t reflect.Type) *arshaler {
   127  	var fncs arshaler
   128  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   129  		xe := export.Encoder(enc)
   130  		var stringify bool // always false except `string` tag with StringifyWithLegacySemantics
   131  		if mo.Flags.Has(jsonflags.TagFlags) {
   132  			stringify = mo.Flags.Get(jsonflags.StringTag) && mo.Flags.Get(jsonflags.StringifyWithLegacySemantics)
   133  			if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
   134  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
   135  			}
   136  			if mo.Flags.Has(jsonflags.FormatTag) {
   137  				return newInvalidFormatError(enc, t)
   138  			}
   139  		}
   140  
   141  		// Optimize for marshaling without preceding whitespace.
   142  		if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify && !xe.Tokens.Last.NeedObjectName() {
   143  			xe.Buf = strconv.AppendBool(xe.Tokens.MayAppendDelim(xe.Buf, 't'), va.Bool())
   144  			xe.Tokens.Last.Increment()
   145  			if xe.NeedFlush() {
   146  				return xe.Flush()
   147  			}
   148  			return nil
   149  		}
   150  
   151  		if stringify {
   152  			if va.Bool() {
   153  				return enc.WriteToken(jsontext.String("true"))
   154  			} else {
   155  				return enc.WriteToken(jsontext.String("false"))
   156  			}
   157  		}
   158  		return enc.WriteToken(jsontext.Bool(va.Bool()))
   159  	}
   160  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   161  		var stringify bool // always false except `string` tag with StringifyWithLegacySemantics
   162  		if uo.Flags.Has(jsonflags.TagFlags) {
   163  			stringify = uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics)
   164  			if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
   165  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
   166  			}
   167  			if uo.Flags.Has(jsonflags.FormatTag) {
   168  				return newInvalidFormatError(dec, t)
   169  			}
   170  		}
   171  		tok, err := dec.ReadToken()
   172  		if err != nil {
   173  			return err
   174  		}
   175  		k := tok.Kind()
   176  		switch k {
   177  		case 'n':
   178  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   179  				va.SetBool(false)
   180  			}
   181  			return nil
   182  		case 't', 'f':
   183  			if !stringify {
   184  				va.SetBool(tok.Bool())
   185  				return nil
   186  			}
   187  		case '"':
   188  			if stringify {
   189  				switch tok.String() {
   190  				case "true":
   191  					va.SetBool(true)
   192  				case "false":
   193  					va.SetBool(false)
   194  				default:
   195  					if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && tok.String() == "null" {
   196  						if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   197  							va.SetBool(false)
   198  						}
   199  						return nil
   200  					}
   201  					return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
   202  				}
   203  				return nil
   204  			}
   205  		}
   206  		return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
   207  	}
   208  	return &fncs
   209  }
   210  
   211  func makeStringArshaler(t reflect.Type) *arshaler {
   212  	var fncs arshaler
   213  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   214  		xe := export.Encoder(enc)
   215  		var stringify bool // always false except `string` tag with StringifyWithLegacySemantics
   216  		if mo.Flags.Has(jsonflags.TagFlags) {
   217  			stringify = mo.Flags.Get(jsonflags.StringTag) && mo.Flags.Get(jsonflags.StringifyWithLegacySemantics)
   218  			if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
   219  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
   220  			}
   221  			if mo.Flags.Has(jsonflags.FormatTag) {
   222  				return newInvalidFormatError(enc, t)
   223  			}
   224  		}
   225  
   226  		// Optimize for marshaling without preceding whitespace.
   227  		s := va.String()
   228  		if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify && !xe.Tokens.Last.NeedObjectName() {
   229  			b := xe.Buf
   230  			b = xe.Tokens.MayAppendDelim(b, '"')
   231  			b, err := jsonwire.AppendQuote(b, []byte(s), &mo.Flags)
   232  			if err == nil {
   233  				xe.Buf = b
   234  				xe.Tokens.Last.Increment()
   235  				if xe.NeedFlush() {
   236  					return xe.Flush()
   237  				}
   238  				return nil
   239  			}
   240  			// Otherwise, the string contains invalid UTF-8,
   241  			// so let the logic below construct the proper error.
   242  		}
   243  
   244  		if stringify {
   245  			b, err := jsonwire.AppendQuote(nil, []byte(s), &mo.Flags)
   246  			if err != nil {
   247  				return newMarshalErrorBefore(enc, t, &jsontext.SyntacticError{Err: err})
   248  			}
   249  			q, err := jsontext.AppendQuote(nil, b)
   250  			if err != nil {
   251  				panic("BUG: second AppendQuote should never fail: " + err.Error())
   252  			}
   253  			return enc.WriteValue(q)
   254  		}
   255  		return enc.WriteToken(jsontext.String(s))
   256  	}
   257  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   258  		xd := export.Decoder(dec)
   259  		var stringify bool // always false except `string` tag with StringifyWithLegacySemantics
   260  		if uo.Flags.Has(jsonflags.TagFlags) {
   261  			stringify = uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics)
   262  			if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) {
   263  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
   264  			}
   265  			if uo.Flags.Has(jsonflags.FormatTag) {
   266  				return newInvalidFormatError(dec, t)
   267  			}
   268  		}
   269  		var flags jsonwire.ValueFlags
   270  		val, err := xd.ReadValue(&flags)
   271  		if err != nil {
   272  			return err
   273  		}
   274  		k := val.Kind()
   275  		switch k {
   276  		case 'n':
   277  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   278  				va.SetString("")
   279  			}
   280  			return nil
   281  		case '"':
   282  			val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
   283  			if stringify {
   284  				if string(val) == "null" {
   285  					if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   286  						va.SetString("")
   287  					}
   288  					return nil
   289  				}
   290  				val, err = jsontext.AppendUnquote(nil, val)
   291  				if err != nil {
   292  					return newUnmarshalErrorAfter(dec, t, err)
   293  				}
   294  			}
   295  			if xd.StringCache == nil {
   296  				xd.StringCache = new(stringCache)
   297  			}
   298  			str := makeString(xd.StringCache, val)
   299  			va.SetString(str)
   300  			return nil
   301  		}
   302  		return newUnmarshalErrorAfter(dec, t, nil)
   303  	}
   304  	return &fncs
   305  }
   306  
   307  var (
   308  	appendEncodeBase16    = hex.AppendEncode
   309  	appendEncodeBase32    = base32.StdEncoding.AppendEncode
   310  	appendEncodeBase32Hex = base32.HexEncoding.AppendEncode
   311  	appendEncodeBase64    = base64.StdEncoding.AppendEncode
   312  	appendEncodeBase64URL = base64.URLEncoding.AppendEncode
   313  	encodedLenBase16      = hex.EncodedLen
   314  	encodedLenBase32      = base32.StdEncoding.EncodedLen
   315  	encodedLenBase32Hex   = base32.HexEncoding.EncodedLen
   316  	encodedLenBase64      = base64.StdEncoding.EncodedLen
   317  	encodedLenBase64URL   = base64.URLEncoding.EncodedLen
   318  	appendDecodeBase16    = hex.AppendDecode
   319  	appendDecodeBase32    = base32.StdEncoding.AppendDecode
   320  	appendDecodeBase32Hex = base32.HexEncoding.AppendDecode
   321  	appendDecodeBase64    = base64.StdEncoding.AppendDecode
   322  	appendDecodeBase64URL = base64.URLEncoding.AppendDecode
   323  )
   324  
   325  func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
   326  	// NOTE: This handles both []~byte and [N]~byte.
   327  	// The v2 default is to treat a []namedByte as equivalent to []T
   328  	// since being able to convert []namedByte to []byte relies on
   329  	// dubious Go reflection behavior (see https://go.dev/issue/24746).
   330  	// For v1 emulation, we use jsonflags.FormatBytesWithLegacySemantics
   331  	// to forcibly treat []namedByte as a []byte.
   332  	marshalArray := fncs.marshal
   333  	isNamedByte := t.Elem().PkgPath() != ""
   334  	hasMarshaler := implementsAny(t.Elem(), allMarshalerTypes...)
   335  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   336  		if !mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && isNamedByte {
   337  			return marshalArray(enc, va, mo) // treat as []T or [N]T
   338  		}
   339  		xe := export.Encoder(enc)
   340  		appendEncode := appendEncodeBase64
   341  		if mo.Flags.Has(jsonflags.TagFlags | jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics | jsonflags.FormatNilSliceAsNull) {
   342  			switch {
   343  			case mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics):
   344  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
   345  			case mo.Flags.Has(jsonflags.FormatTag):
   346  				switch mo.Format {
   347  				case "base64":
   348  					appendEncode = appendEncodeBase64
   349  				case "base64url":
   350  					appendEncode = appendEncodeBase64URL
   351  				case "base32":
   352  					appendEncode = appendEncodeBase32
   353  				case "base32hex":
   354  					appendEncode = appendEncodeBase32Hex
   355  				case "base16", "hex":
   356  					appendEncode = appendEncodeBase16
   357  				case "array":
   358  					mo.Flags.Clear(jsonflags.FormatTag)
   359  					return marshalArray(enc, va, mo)
   360  				default:
   361  					return newInvalidFormatError(enc, t)
   362  				}
   363  			case mo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array:
   364  				return marshalArray(enc, va, mo)
   365  			case mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && hasMarshaler:
   366  				return marshalArray(enc, va, mo)
   367  			}
   368  			if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && va.Kind() == reflect.Slice && va.IsNil() {
   369  				// TODO: Provide an "emitempty" format override?
   370  				return enc.WriteToken(jsontext.Null)
   371  			}
   372  		}
   373  		return xe.AppendRaw('"', true, func(b []byte) ([]byte, error) {
   374  			return appendEncode(b, va.Bytes()), nil
   375  		})
   376  	}
   377  	unmarshalArray := fncs.unmarshal
   378  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   379  		if !uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && isNamedByte {
   380  			return unmarshalArray(dec, va, uo) // treat as []T or [N]T
   381  		}
   382  		xd := export.Decoder(dec)
   383  		appendDecode, encodedLen := appendDecodeBase64, encodedLenBase64
   384  		if uo.Flags.Has(jsonflags.TagFlags | jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics) {
   385  			switch {
   386  			case uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics):
   387  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
   388  			case uo.Flags.Has(jsonflags.FormatTag):
   389  				switch uo.Format {
   390  				case "base64":
   391  					appendDecode, encodedLen = appendDecodeBase64, encodedLenBase64
   392  				case "base64url":
   393  					appendDecode, encodedLen = appendDecodeBase64URL, encodedLenBase64URL
   394  				case "base32":
   395  					appendDecode, encodedLen = appendDecodeBase32, encodedLenBase32
   396  				case "base32hex":
   397  					appendDecode, encodedLen = appendDecodeBase32Hex, encodedLenBase32Hex
   398  				case "base16", "hex":
   399  					appendDecode, encodedLen = appendDecodeBase16, encodedLenBase16
   400  				case "array":
   401  					uo.Flags.Clear(jsonflags.FormatTag)
   402  					return unmarshalArray(dec, va, uo)
   403  				default:
   404  					return newInvalidFormatError(dec, t)
   405  				}
   406  			case uo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array:
   407  				return unmarshalArray(dec, va, uo)
   408  			case uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && dec.PeekKind() == '[':
   409  				return unmarshalArray(dec, va, uo)
   410  			}
   411  		}
   412  		var flags jsonwire.ValueFlags
   413  		val, err := xd.ReadValue(&flags)
   414  		if err != nil {
   415  			return err
   416  		}
   417  		k := val.Kind()
   418  		switch k {
   419  		case 'n':
   420  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) || va.Kind() != reflect.Array {
   421  				va.SetZero()
   422  			}
   423  			return nil
   424  		case '"':
   425  			// NOTE: The v2 default is to strictly comply with RFC 4648.
   426  			// Section 3.2 specifies that padding is required.
   427  			// Section 3.3 specifies that non-alphabet characters
   428  			// (e.g., '\r' or '\n') must be rejected.
   429  			// Section 3.5 specifies that unnecessary non-zero bits in
   430  			// the last quantum may be rejected. Since this is optional,
   431  			// we do not reject such inputs.
   432  			val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
   433  			b, err := appendDecode(va.Bytes()[:0], val)
   434  			if err != nil {
   435  				return newUnmarshalErrorAfter(dec, t, err)
   436  			}
   437  			if len(val) != encodedLen(len(b)) && !uo.Flags.Get(jsonflags.ParseBytesWithLooseRFC4648) {
   438  				// TODO(https://go.dev/issue/53845): RFC 4648, section 3.3,
   439  				// specifies that non-alphabet characters must be rejected.
   440  				// Unfortunately, the "base32" and "base64" packages allow
   441  				// '\r' and '\n' characters by default.
   442  				i := bytes.IndexAny(val, "\r\n")
   443  				err := fmt.Errorf("illegal character %s at offset %d", jsonwire.QuoteRune(val[i:]), i)
   444  				return newUnmarshalErrorAfter(dec, t, err)
   445  			}
   446  
   447  			if va.Kind() == reflect.Array {
   448  				dst := va.Bytes()
   449  				clear(dst[copy(dst, b):]) // noop if len(b) >= len(dst)
   450  				if len(b) != len(dst) && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
   451  					err := fmt.Errorf("decoded length of %d mismatches array length of %d", len(b), len(dst))
   452  					return newUnmarshalErrorAfter(dec, t, err)
   453  				}
   454  			} else {
   455  				if b == nil {
   456  					b = []byte{}
   457  				}
   458  				va.SetBytes(b)
   459  			}
   460  			return nil
   461  		}
   462  		return newUnmarshalErrorAfter(dec, t, nil)
   463  	}
   464  	return fncs
   465  }
   466  
   467  func makeIntArshaler(t reflect.Type) *arshaler {
   468  	var fncs arshaler
   469  	bits := t.Bits()
   470  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   471  		xe := export.Encoder(enc)
   472  		stringify := xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
   473  		if mo.Flags.Has(jsonflags.FormatTag) {
   474  			return newInvalidFormatError(enc, t)
   475  		}
   476  
   477  		// Optimize for marshaling without preceding whitespace or string escaping.
   478  		if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify {
   479  			xe.Buf = strconv.AppendInt(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Int(), 10)
   480  			xe.Tokens.Last.Increment()
   481  			if xe.NeedFlush() {
   482  				return xe.Flush()
   483  			}
   484  			return nil
   485  		}
   486  
   487  		k := stringOrNumberKind(stringify)
   488  		return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) {
   489  			return strconv.AppendInt(b, va.Int(), 10), nil
   490  		})
   491  	}
   492  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   493  		xd := export.Decoder(dec)
   494  		stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
   495  		if uo.Flags.Has(jsonflags.FormatTag) {
   496  			return newInvalidFormatError(dec, t)
   497  		}
   498  		var flags jsonwire.ValueFlags
   499  		val, err := xd.ReadValue(&flags)
   500  		if err != nil {
   501  			return err
   502  		}
   503  		k := val.Kind()
   504  		switch k {
   505  		case 'n':
   506  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   507  				va.SetInt(0)
   508  			}
   509  			return nil
   510  		case '"':
   511  			if !stringify {
   512  				break
   513  			}
   514  			val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
   515  			if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
   516  				// For historical reasons, v1 parsed a quoted number
   517  				// according to the Go syntax and permitted a quoted null.
   518  				// See https://go.dev/issue/75619
   519  				n, err := strconv.ParseInt(string(val), 10, bits)
   520  				if err != nil {
   521  					if string(val) == "null" {
   522  						if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   523  							va.SetInt(0)
   524  						}
   525  						return nil
   526  					}
   527  					return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
   528  				}
   529  				va.SetInt(n)
   530  				return nil
   531  			}
   532  			fallthrough
   533  		case '0':
   534  			if stringify && k == '0' {
   535  				break
   536  			}
   537  			var negOffset int
   538  			neg := len(val) > 0 && val[0] == '-'
   539  			if neg {
   540  				negOffset = 1
   541  			}
   542  			n, ok := jsonwire.ParseUint(val[negOffset:])
   543  			maxInt := uint64(1) << (bits - 1)
   544  			overflow := (neg && n > maxInt) || (!neg && n > maxInt-1)
   545  			if !ok {
   546  				if n != math.MaxUint64 {
   547  					return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
   548  				}
   549  				overflow = true
   550  			}
   551  			if overflow {
   552  				return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange)
   553  			}
   554  			if neg {
   555  				va.SetInt(int64(-n))
   556  			} else {
   557  				va.SetInt(int64(+n))
   558  			}
   559  			return nil
   560  		}
   561  		return newUnmarshalErrorAfter(dec, t, nil)
   562  	}
   563  	return &fncs
   564  }
   565  
   566  func makeUintArshaler(t reflect.Type) *arshaler {
   567  	var fncs arshaler
   568  	bits := t.Bits()
   569  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   570  		xe := export.Encoder(enc)
   571  		stringify := xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
   572  		if mo.Flags.Has(jsonflags.FormatTag) {
   573  			return newInvalidFormatError(enc, t)
   574  		}
   575  
   576  		// Optimize for marshaling without preceding whitespace or string escaping.
   577  		if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify {
   578  			xe.Buf = strconv.AppendUint(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Uint(), 10)
   579  			xe.Tokens.Last.Increment()
   580  			if xe.NeedFlush() {
   581  				return xe.Flush()
   582  			}
   583  			return nil
   584  		}
   585  
   586  		k := stringOrNumberKind(stringify)
   587  		return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) {
   588  			return strconv.AppendUint(b, va.Uint(), 10), nil
   589  		})
   590  	}
   591  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   592  		xd := export.Decoder(dec)
   593  		stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
   594  		if uo.Flags.Has(jsonflags.FormatTag) {
   595  			return newInvalidFormatError(dec, t)
   596  		}
   597  		var flags jsonwire.ValueFlags
   598  		val, err := xd.ReadValue(&flags)
   599  		if err != nil {
   600  			return err
   601  		}
   602  		k := val.Kind()
   603  		switch k {
   604  		case 'n':
   605  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   606  				va.SetUint(0)
   607  			}
   608  			return nil
   609  		case '"':
   610  			if !stringify {
   611  				break
   612  			}
   613  			val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
   614  			if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
   615  				// For historical reasons, v1 parsed a quoted number
   616  				// according to the Go syntax and permitted a quoted null.
   617  				// See https://go.dev/issue/75619
   618  				n, err := strconv.ParseUint(string(val), 10, bits)
   619  				if err != nil {
   620  					if string(val) == "null" {
   621  						if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   622  							va.SetUint(0)
   623  						}
   624  						return nil
   625  					}
   626  					return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
   627  				}
   628  				va.SetUint(n)
   629  				return nil
   630  			}
   631  			fallthrough
   632  		case '0':
   633  			if stringify && k == '0' {
   634  				break
   635  			}
   636  			n, ok := jsonwire.ParseUint(val)
   637  			maxUint := uint64(1) << bits
   638  			overflow := n > maxUint-1
   639  			if !ok {
   640  				if n != math.MaxUint64 {
   641  					return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
   642  				}
   643  				overflow = true
   644  			}
   645  			if overflow {
   646  				return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange)
   647  			}
   648  			va.SetUint(n)
   649  			return nil
   650  		}
   651  		return newUnmarshalErrorAfter(dec, t, nil)
   652  	}
   653  	return &fncs
   654  }
   655  
   656  func makeFloatArshaler(t reflect.Type) *arshaler {
   657  	var fncs arshaler
   658  	bits := t.Bits()
   659  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   660  		xe := export.Encoder(enc)
   661  		stringify := xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
   662  		var allowNonFinite bool
   663  		if mo.Flags.Has(jsonflags.FormatTag) {
   664  			if mo.Format == "nonfinite" {
   665  				allowNonFinite = true
   666  			} else {
   667  				return newInvalidFormatError(enc, t)
   668  			}
   669  		}
   670  
   671  		fv := va.Float()
   672  		if math.IsNaN(fv) || math.IsInf(fv, 0) {
   673  			if !allowNonFinite {
   674  				err := fmt.Errorf("unsupported value: %v", fv)
   675  				if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   676  					err = &internal.ValueError{Val: va.Interface(), Err: err}
   677  				}
   678  				return newMarshalErrorBefore(enc, t, err)
   679  			}
   680  			return enc.WriteToken(jsontext.Float(fv))
   681  		}
   682  
   683  		// Optimize for marshaling without preceding whitespace or string escaping.
   684  		if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify {
   685  			xe.Buf = jsonwire.AppendFloat(xe.Tokens.MayAppendDelim(xe.Buf, '0'), fv, bits)
   686  			xe.Tokens.Last.Increment()
   687  			if xe.NeedFlush() {
   688  				return xe.Flush()
   689  			}
   690  			return nil
   691  		}
   692  
   693  		k := stringOrNumberKind(stringify)
   694  		return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) {
   695  			return jsonwire.AppendFloat(b, va.Float(), bits), nil
   696  		})
   697  	}
   698  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   699  		xd := export.Decoder(dec)
   700  		stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
   701  		var allowNonFinite bool
   702  		if uo.Flags.Has(jsonflags.FormatTag) {
   703  			if uo.Format == "nonfinite" {
   704  				allowNonFinite = true
   705  			} else {
   706  				return newInvalidFormatError(dec, t)
   707  			}
   708  		}
   709  
   710  		var flags jsonwire.ValueFlags
   711  		val, err := xd.ReadValue(&flags)
   712  		if err != nil {
   713  			return err
   714  		}
   715  		k := val.Kind()
   716  		switch k {
   717  		case 'n':
   718  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   719  				va.SetFloat(0)
   720  			}
   721  			return nil
   722  		case '"':
   723  			val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
   724  			if allowNonFinite {
   725  				switch string(val) {
   726  				case "NaN":
   727  					va.SetFloat(math.NaN())
   728  					return nil
   729  				case "Infinity":
   730  					va.SetFloat(math.Inf(+1))
   731  					return nil
   732  				case "-Infinity":
   733  					va.SetFloat(math.Inf(-1))
   734  					return nil
   735  				}
   736  			}
   737  			if !stringify {
   738  				break
   739  			}
   740  			if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
   741  				// For historical reasons, v1 parsed a quoted number
   742  				// according to the Go syntax and permitted a quoted null.
   743  				// See https://go.dev/issue/75619
   744  				n, err := strconv.ParseFloat(string(val), bits)
   745  				if err != nil {
   746  					if string(val) == "null" {
   747  						if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
   748  							va.SetFloat(0)
   749  						}
   750  						return nil
   751  					}
   752  					return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
   753  				}
   754  				va.SetFloat(n)
   755  				return nil
   756  			}
   757  			if n, err := jsonwire.ConsumeNumber(val); n != len(val) || err != nil {
   758  				return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax)
   759  			}
   760  			fallthrough
   761  		case '0':
   762  			if stringify && k == '0' {
   763  				break
   764  			}
   765  			fv, err := strconv.ParseFloat(string(val), bits)
   766  			if err != nil {
   767  				return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err))
   768  			}
   769  			va.SetFloat(fv)
   770  			return nil
   771  		}
   772  		return newUnmarshalErrorAfter(dec, t, nil)
   773  	}
   774  	return &fncs
   775  }
   776  
   777  func makeMapArshaler(t reflect.Type) *arshaler {
   778  	// NOTE: The logic below disables namespaces for tracking duplicate names
   779  	// when handling map keys with a unique representation.
   780  
   781  	// NOTE: Values retrieved from a map are not addressable,
   782  	// so we shallow copy the values to make them addressable and
   783  	// store them back into the map afterwards.
   784  
   785  	var fncs arshaler
   786  	var (
   787  		once    sync.Once
   788  		keyFncs *arshaler
   789  		valFncs *arshaler
   790  	)
   791  	init := func() {
   792  		keyFncs = lookupArshaler(t.Key())
   793  		valFncs = lookupArshaler(t.Elem())
   794  	}
   795  	nillableLegacyKey := t.Key().Kind() == reflect.Pointer &&
   796  		implementsAny(t.Key(), textMarshalerType, textAppenderType)
   797  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
   798  		// Check for cycles.
   799  		xe := export.Encoder(enc)
   800  		if xe.Tokens.Depth() > startDetectingCyclesAfter {
   801  			if err := visitPointer(&xe.SeenPointers, va.Value); err != nil {
   802  				return newMarshalErrorBefore(enc, t, err)
   803  			}
   804  			defer leavePointer(&xe.SeenPointers, va.Value)
   805  		}
   806  
   807  		emitNull := mo.Flags.Get(jsonflags.FormatNilMapAsNull)
   808  		if mo.Flags.Has(jsonflags.TagFlags) {
   809  			if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   810  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
   811  			}
   812  			if mo.Flags.Has(jsonflags.FormatTag) {
   813  				switch mo.Format {
   814  				case "emitnull":
   815  					emitNull = true
   816  				case "emitempty":
   817  					emitNull = false
   818  				default:
   819  					return newInvalidFormatError(enc, t)
   820  				}
   821  			}
   822  		}
   823  
   824  		// Handle empty maps.
   825  		n := va.Len()
   826  		if n == 0 {
   827  			if emitNull && va.IsNil() {
   828  				return enc.WriteToken(jsontext.Null)
   829  			}
   830  			// Optimize for marshaling an empty map without any preceding whitespace.
   831  			if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() {
   832  				xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '{'), "{}"...)
   833  				xe.Tokens.Last.Increment()
   834  				if xe.NeedFlush() {
   835  					return xe.Flush()
   836  				}
   837  				return nil
   838  			}
   839  		}
   840  
   841  		once.Do(init)
   842  		if err := enc.WriteToken(jsontext.BeginObject); err != nil {
   843  			return err
   844  		}
   845  		if n > 0 {
   846  			nonDefaultKey := keyFncs.nonDefault
   847  			marshalKey := keyFncs.marshal
   848  			marshalVal := valFncs.marshal
   849  			if mo.Marshalers != nil {
   850  				var ok bool
   851  				marshalKey, ok = mo.Marshalers.(*Marshalers).lookup(marshalKey, t.Key())
   852  				marshalVal, _ = mo.Marshalers.(*Marshalers).lookup(marshalVal, t.Elem())
   853  				nonDefaultKey = nonDefaultKey || ok
   854  			}
   855  			k := newAddressableValue(t.Key())
   856  			v := newAddressableValue(t.Elem())
   857  
   858  			// A Go map guarantees that each entry has a unique key.
   859  			// As such, disable the expensive duplicate name check if we know
   860  			// that every Go key will serialize as a unique JSON string.
   861  			if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), mo.Flags.Get(jsonflags.AllowInvalidUTF8)) {
   862  				xe.Tokens.Last.DisableNamespace()
   863  			}
   864  
   865  			switch {
   866  			case !mo.Flags.Get(jsonflags.Deterministic) || n <= 1:
   867  				for iter := va.Value.MapRange(); iter.Next(); {
   868  					k.SetIterKey(iter)
   869  					err := marshalKey(enc, k, mo)
   870  					if err != nil {
   871  						if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
   872  							errors.Is(err, jsontext.ErrNonStringName) && nillableLegacyKey && k.IsNil() {
   873  							err = enc.WriteToken(jsontext.String(""))
   874  						}
   875  						if err != nil {
   876  							if serr, ok := err.(*jsontext.SyntacticError); ok && serr.Err == jsontext.ErrNonStringName {
   877  								err = newMarshalErrorBefore(enc, k.Type(), err)
   878  							}
   879  							return err
   880  						}
   881  					}
   882  					v.SetIterValue(iter)
   883  					if err := marshalVal(enc, v, mo); err != nil {
   884  						return err
   885  					}
   886  				}
   887  			case !nonDefaultKey && t.Key().Kind() == reflect.String:
   888  				names := getStrings(n)
   889  				for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ {
   890  					k.SetIterKey(iter)
   891  					(*names)[i] = k.String()
   892  				}
   893  				slices.Sort(*names)
   894  				for _, name := range *names {
   895  					if err := enc.WriteToken(jsontext.String(name)); err != nil {
   896  						return err
   897  					}
   898  					// TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf.
   899  					k.SetString(name)
   900  					v.Set(va.MapIndex(k.Value))
   901  					if err := marshalVal(enc, v, mo); err != nil {
   902  						return err
   903  					}
   904  				}
   905  				putStrings(names)
   906  			default:
   907  				type member struct {
   908  					name string // unquoted name
   909  					key  addressableValue
   910  					val  addressableValue
   911  				}
   912  				members := make([]member, n)
   913  				keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n)
   914  				vals := reflect.MakeSlice(reflect.SliceOf(t.Elem()), n, n)
   915  				for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ {
   916  					// Marshal the member name.
   917  					k := addressableValue{keys.Index(i), true} // indexed slice element is always addressable
   918  					k.SetIterKey(iter)
   919  					v := addressableValue{vals.Index(i), true} // indexed slice element is always addressable
   920  					v.SetIterValue(iter)
   921  					err := marshalKey(enc, k, mo)
   922  					if err != nil {
   923  						if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) &&
   924  							errors.Is(err, jsontext.ErrNonStringName) && nillableLegacyKey && k.IsNil() {
   925  							err = enc.WriteToken(jsontext.String(""))
   926  						}
   927  						if err != nil {
   928  							if serr, ok := err.(*jsontext.SyntacticError); ok && serr.Err == jsontext.ErrNonStringName {
   929  								err = newMarshalErrorBefore(enc, k.Type(), err)
   930  							}
   931  							return err
   932  						}
   933  					}
   934  					name := xe.UnwriteOnlyObjectMemberName()
   935  					members[i] = member{name, k, v}
   936  				}
   937  				// TODO: If AllowDuplicateNames is enabled, then sort according
   938  				// to reflect.Value as well if the names are equal.
   939  				// See internal/fmtsort.
   940  				slices.SortFunc(members, func(x, y member) int {
   941  					return strings.Compare(x.name, y.name)
   942  				})
   943  				for _, member := range members {
   944  					if err := enc.WriteToken(jsontext.String(member.name)); err != nil {
   945  						return err
   946  					}
   947  					if err := marshalVal(enc, member.val, mo); err != nil {
   948  						return err
   949  					}
   950  				}
   951  			}
   952  		}
   953  		if err := enc.WriteToken(jsontext.EndObject); err != nil {
   954  			return err
   955  		}
   956  		return nil
   957  	}
   958  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
   959  		xd := export.Decoder(dec)
   960  		if uo.Flags.Has(jsonflags.TagFlags) {
   961  			if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
   962  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
   963  			}
   964  			if uo.Flags.Has(jsonflags.FormatTag) {
   965  				switch uo.Format {
   966  				case "emitnull", "emitempty":
   967  				default:
   968  					return newInvalidFormatError(dec, t)
   969  				}
   970  			}
   971  		}
   972  		tok, err := dec.ReadToken()
   973  		if err != nil {
   974  			return err
   975  		}
   976  		k := tok.Kind()
   977  		switch k {
   978  		case 'n':
   979  			va.SetZero()
   980  			return nil
   981  		case '{':
   982  			once.Do(init)
   983  			if va.IsNil() {
   984  				va.Set(reflect.MakeMap(t))
   985  			}
   986  
   987  			nonDefaultKey := keyFncs.nonDefault
   988  			unmarshalKey := keyFncs.unmarshal
   989  			unmarshalVal := valFncs.unmarshal
   990  			if uo.Unmarshalers != nil {
   991  				var ok bool
   992  				unmarshalKey, ok = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshalKey, t.Key())
   993  				unmarshalVal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshalVal, t.Elem())
   994  				nonDefaultKey = nonDefaultKey || ok
   995  			}
   996  			k := newAddressableValue(t.Key())
   997  			v := newAddressableValue(t.Elem())
   998  
   999  			// Manually check for duplicate entries by virtue of whether the
  1000  			// unmarshaled key already exists in the destination Go map.
  1001  			// Consequently, syntactically different names (e.g., "0" and "-0")
  1002  			// will be rejected as duplicates since they semantically refer
  1003  			// to the same Go value. This is an unusual interaction
  1004  			// between syntax and semantics, but is more correct.
  1005  			if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), uo.Flags.Get(jsonflags.AllowInvalidUTF8)) {
  1006  				xd.Tokens.Last.DisableNamespace()
  1007  			}
  1008  
  1009  			// In the rare case where the map is not already empty,
  1010  			// then we need to manually track which keys we already saw
  1011  			// since existing presence alone is insufficient to indicate
  1012  			// whether the input had a duplicate name.
  1013  			var seen reflect.Value
  1014  			if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && va.Len() > 0 {
  1015  				seen = reflect.MakeMap(reflect.MapOf(k.Type(), emptyStructType))
  1016  			}
  1017  
  1018  			var errUnmarshal error
  1019  			for dec.PeekKind() != '}' {
  1020  				// Unmarshal the map entry key.
  1021  				k.SetZero()
  1022  				err := unmarshalKey(dec, k, uo)
  1023  				if err != nil {
  1024  					if isFatalError(err, uo.Flags) {
  1025  						return err
  1026  					}
  1027  					if err := dec.SkipValue(); err != nil {
  1028  						return err
  1029  					}
  1030  					errUnmarshal = cmp.Or(errUnmarshal, err)
  1031  					continue
  1032  				}
  1033  				if k.Kind() == reflect.Interface && !k.IsNil() && !k.Elem().Type().Comparable() {
  1034  					err := newUnmarshalErrorAfter(dec, t, fmt.Errorf("invalid incomparable key type %v", k.Elem().Type()))
  1035  					if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1036  						return err
  1037  					}
  1038  					if err2 := dec.SkipValue(); err2 != nil {
  1039  						return err2
  1040  					}
  1041  					errUnmarshal = cmp.Or(errUnmarshal, err)
  1042  					continue
  1043  				}
  1044  
  1045  				// Check if a pre-existing map entry value exists for this key.
  1046  				if v2 := va.MapIndex(k.Value); v2.IsValid() {
  1047  					if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && (!seen.IsValid() || seen.MapIndex(k.Value).IsValid()) {
  1048  						// TODO: Unread the object name.
  1049  						name := xd.PreviousTokenOrValue()
  1050  						return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(name))
  1051  					}
  1052  					if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
  1053  						v.Set(v2)
  1054  					} else {
  1055  						v.SetZero()
  1056  					}
  1057  				} else {
  1058  					v.SetZero()
  1059  				}
  1060  
  1061  				// Unmarshal the map entry value.
  1062  				err = unmarshalVal(dec, v, uo)
  1063  				va.SetMapIndex(k.Value, v.Value)
  1064  				if seen.IsValid() {
  1065  					seen.SetMapIndex(k.Value, reflect.Zero(emptyStructType))
  1066  				}
  1067  				if err != nil {
  1068  					if isFatalError(err, uo.Flags) {
  1069  						return err
  1070  					}
  1071  					errUnmarshal = cmp.Or(errUnmarshal, err)
  1072  				}
  1073  			}
  1074  			if _, err := dec.ReadToken(); err != nil {
  1075  				return err
  1076  			}
  1077  			return errUnmarshal
  1078  		}
  1079  		return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
  1080  	}
  1081  	return &fncs
  1082  }
  1083  
  1084  // mapKeyWithUniqueRepresentation reports whether all possible values of k
  1085  // marshal to a different JSON value, and whether all possible JSON values
  1086  // that can unmarshal into k unmarshal to different Go values.
  1087  // In other words, the representation must be a bijection.
  1088  func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool {
  1089  	switch k {
  1090  	case reflect.Bool,
  1091  		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  1092  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1093  		return true
  1094  	case reflect.String:
  1095  		// For strings, we have to be careful since names with invalid UTF-8
  1096  		// may unescape to the same Go string value.
  1097  		return !allowInvalidUTF8
  1098  	default:
  1099  		// Floating-point kinds are not listed above since NaNs
  1100  		// can appear multiple times and all serialize as "NaN".
  1101  		return false
  1102  	}
  1103  }
  1104  
  1105  var errNilField = errors.New("cannot set embedded pointer to unexported struct type")
  1106  var errInvalidStringTag = errors.New("invalid use of `string` tag option")
  1107  
  1108  func makeStructArshaler(t reflect.Type) *arshaler {
  1109  	// NOTE: The logic below disables namespaces for tracking duplicate names
  1110  	// and does the tracking locally with an efficient bit-set based on which
  1111  	// Go struct fields were seen.
  1112  
  1113  	var fncs arshaler
  1114  	var (
  1115  		once    sync.Once
  1116  		fields  structFields
  1117  		errInit *SemanticError
  1118  	)
  1119  	init := func() {
  1120  		fields, errInit = makeStructFields(t)
  1121  	}
  1122  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
  1123  		xe := export.Encoder(enc)
  1124  		if mo.Flags.Has(jsonflags.TagFlags) {
  1125  			if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1126  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
  1127  			}
  1128  			if mo.Flags.Has(jsonflags.FormatTag) {
  1129  				return newInvalidFormatError(enc, t)
  1130  			}
  1131  		}
  1132  		once.Do(init)
  1133  		if errInit != nil && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1134  			return newMarshalErrorBefore(enc, errInit.GoType, errInit.Err)
  1135  		} else if fields.errUnsupportedFormat != nil && !mo.Flags.Get(jsonflags.FormatTagSupported) {
  1136  			return newMarshalErrorBefore(enc, fields.errUnsupportedFormat.GoType, fields.errUnsupportedFormat.Err)
  1137  		}
  1138  
  1139  		if err := enc.WriteToken(jsontext.BeginObject); err != nil {
  1140  			return err
  1141  		}
  1142  		var seenIdxs uintSet
  1143  		prevIdx := -1
  1144  		xe.Tokens.Last.DisableNamespace() // we manually ensure unique names below
  1145  		for i := range fields.flattened {
  1146  			f := &fields.flattened[i]
  1147  			v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable
  1148  			if len(f.index) > 0 {
  1149  				v = v.fieldByIndex(f.index, false)
  1150  				if !v.IsValid() {
  1151  					continue // implies a nil embedded field
  1152  				}
  1153  			}
  1154  
  1155  			// OmitZero skips the field if the Go value is zero,
  1156  			// which we can determine up front without calling the marshaler.
  1157  			if (f.omitzero || mo.Flags.Get(jsonflags.OmitZeroStructFields)) &&
  1158  				((f.isZero == nil && v.IsZero()) || (f.isZero != nil && f.isZero(v))) {
  1159  				continue
  1160  			}
  1161  
  1162  			// Check for the legacy definition of omitempty.
  1163  			if f.omitempty && mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) && isLegacyEmpty(v) {
  1164  				continue
  1165  			}
  1166  
  1167  			marshal := f.fncs.marshal
  1168  			nonDefault := f.fncs.nonDefault
  1169  			if mo.Marshalers != nil {
  1170  				var ok bool
  1171  				marshal, ok = mo.Marshalers.(*Marshalers).lookup(marshal, f.typ)
  1172  				nonDefault = nonDefault || ok
  1173  			}
  1174  
  1175  			// OmitEmpty skips the field if the marshaled JSON value is empty,
  1176  			// which we can know up front if there are no custom marshalers,
  1177  			// otherwise we must marshal the value and unwrite it if empty.
  1178  			if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) &&
  1179  				!nonDefault && f.isEmpty != nil && f.isEmpty(v) {
  1180  				continue // fast path for omitempty
  1181  			}
  1182  
  1183  			// Write the object member name.
  1184  			//
  1185  			// The logic below is semantically equivalent to:
  1186  			//	enc.WriteToken(String(f.name))
  1187  			// but specialized and simplified because:
  1188  			//	1. The Encoder must be expecting an object name.
  1189  			//	2. The object namespace is guaranteed to be disabled.
  1190  			//	3. The object name is guaranteed to be valid and pre-escaped.
  1191  			//	4. There is no need to flush the buffer (for unwrite purposes).
  1192  			//	5. There is no possibility of an error occurring.
  1193  			if optimizeCommon {
  1194  				// Append any delimiters or optional whitespace.
  1195  				b := xe.Buf
  1196  				if xe.Tokens.Last.Length() > 0 {
  1197  					b = append(b, ',')
  1198  					if mo.Flags.Get(jsonflags.SpaceAfterComma) {
  1199  						b = append(b, ' ')
  1200  					}
  1201  				}
  1202  				if mo.Flags.Get(jsonflags.Multiline) {
  1203  					b = xe.AppendIndent(b, xe.Tokens.NeedIndent('"'))
  1204  				}
  1205  
  1206  				// Append the token to the output and to the state machine.
  1207  				n0 := len(b) // offset before calling AppendQuote
  1208  				if !f.nameNeedEscape {
  1209  					b = append(b, f.quotedName...)
  1210  				} else {
  1211  					b, _ = jsonwire.AppendQuote(b, []byte(f.name), &mo.Flags)
  1212  				}
  1213  				xe.Buf = b
  1214  				xe.Names.ReplaceLastQuotedOffset(n0)
  1215  				xe.Tokens.Last.Increment()
  1216  			} else {
  1217  				if err := enc.WriteToken(jsontext.String(f.name)); err != nil {
  1218  					return err
  1219  				}
  1220  			}
  1221  
  1222  			// Write the object member value.
  1223  			flagsOriginal := mo.Flags
  1224  			if f.string {
  1225  				mo.Flags.Set(jsonflags.StringTag | 1)
  1226  			}
  1227  			if f.format != "" {
  1228  				mo.Flags.Set(jsonflags.FormatTag | 1)
  1229  				mo.Format = f.format
  1230  			}
  1231  			err := marshal(enc, v, mo)
  1232  			mo.Flags = flagsOriginal
  1233  			mo.Format = ""
  1234  			if err != nil {
  1235  				return err
  1236  			}
  1237  
  1238  			// Try unwriting the member if empty (slow path for omitempty).
  1239  			if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) {
  1240  				var prevName *string
  1241  				if prevIdx >= 0 {
  1242  					prevName = &fields.flattened[prevIdx].name
  1243  				}
  1244  				if xe.UnwriteEmptyObjectMember(prevName) {
  1245  					continue
  1246  				}
  1247  			}
  1248  
  1249  			// Remember the previous written object member.
  1250  			// The set of seen fields only needs to be updated to detect
  1251  			// duplicate names with those from the embedded fallback.
  1252  			if !mo.Flags.Get(jsonflags.AllowDuplicateNames) && fields.embeddedFallback != nil {
  1253  				seenIdxs.insert(uint(f.id))
  1254  			}
  1255  			prevIdx = f.id
  1256  		}
  1257  		if fields.embeddedFallback != nil {
  1258  			var insertUnquotedName func([]byte) bool
  1259  			if !mo.Flags.Get(jsonflags.AllowDuplicateNames) {
  1260  				insertUnquotedName = func(name []byte) bool {
  1261  					// Check that the name from embedded fallback does not match
  1262  					// one of the previously marshaled names from known fields.
  1263  					if foldedFields := fields.lookupByFoldedName(name); len(foldedFields) > 0 {
  1264  						if f := fields.byActualName[string(name)]; f != nil {
  1265  							return seenIdxs.insert(uint(f.id))
  1266  						}
  1267  						for _, f := range foldedFields {
  1268  							if f.matchFoldedName(name, &mo.Flags) {
  1269  								return seenIdxs.insert(uint(f.id))
  1270  							}
  1271  						}
  1272  					}
  1273  
  1274  					// Check that the name does not match any other name
  1275  					// previously marshaled from the embedded fallback.
  1276  					return xe.Namespaces.Last().InsertUnquoted(name)
  1277  				}
  1278  			}
  1279  			if err := marshalEmbeddedFallbackAll(enc, va, mo, fields.embeddedFallback, insertUnquotedName); err != nil {
  1280  				return err
  1281  			}
  1282  		}
  1283  		if err := enc.WriteToken(jsontext.EndObject); err != nil {
  1284  			return err
  1285  		}
  1286  		return nil
  1287  	}
  1288  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1289  		xd := export.Decoder(dec)
  1290  		if uo.Flags.Has(jsonflags.TagFlags) {
  1291  			if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1292  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
  1293  			}
  1294  			if uo.Flags.Has(jsonflags.FormatTag) {
  1295  				return newInvalidFormatError(dec, t)
  1296  			}
  1297  		}
  1298  		tok, err := dec.ReadToken()
  1299  		if err != nil {
  1300  			return err
  1301  		}
  1302  		k := tok.Kind()
  1303  		switch k {
  1304  		case 'n':
  1305  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
  1306  				va.SetZero()
  1307  			}
  1308  			return nil
  1309  		case '{':
  1310  			once.Do(init)
  1311  			if errInit != nil && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1312  				return newUnmarshalErrorAfter(dec, errInit.GoType, errInit.Err)
  1313  			} else if fields.errUnsupportedFormat != nil && !uo.Flags.Get(jsonflags.FormatTagSupported) {
  1314  				return newUnmarshalErrorAfter(dec, fields.errUnsupportedFormat.GoType, fields.errUnsupportedFormat.Err)
  1315  			}
  1316  
  1317  			var seenIdxs uintSet
  1318  			xd.Tokens.Last.DisableNamespace()
  1319  			var errUnmarshal error
  1320  			for dec.PeekKind() != '}' {
  1321  				// Process the object member name.
  1322  				var flags jsonwire.ValueFlags
  1323  				val, err := xd.ReadValue(&flags)
  1324  				if err != nil {
  1325  					return err
  1326  				}
  1327  				name := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
  1328  				f := fields.byActualName[string(name)]
  1329  				if f == nil {
  1330  					var numMatch int
  1331  					for _, f2 := range fields.lookupByFoldedName(name) {
  1332  						if f2.matchFoldedName(name, &uo.Flags) {
  1333  							if f == nil {
  1334  								f = f2 // use first seen name by breadth-first order
  1335  							}
  1336  							numMatch++
  1337  						}
  1338  					}
  1339  					if numMatch > 1 && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1340  						return newUnmarshalErrorAfter(dec, t, errAmbiguousName)
  1341  					}
  1342  					if f == nil {
  1343  						if uo.Flags.Get(jsonflags.RejectUnknownMembers) && fields.embeddedFallback == nil {
  1344  							err := newUnmarshalErrorAfter(dec, t, ErrUnknownName)
  1345  							if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1346  								return err
  1347  							}
  1348  							errUnmarshal = cmp.Or(errUnmarshal, err)
  1349  						}
  1350  						if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && !xd.Namespaces.Last().InsertUnquoted(name) {
  1351  							// TODO: Unread the object name.
  1352  							return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val))
  1353  						}
  1354  
  1355  						if fields.embeddedFallback == nil {
  1356  							// Skip unknown value since we have no place to store it.
  1357  							if err := dec.SkipValue(); err != nil {
  1358  								return err
  1359  							}
  1360  						} else {
  1361  							// Unmarshal into a value capable of storing arbitrary object members.
  1362  							if err := unmarshalEmbeddedFallbackNext(dec, va, uo, fields.embeddedFallback, val, name); err != nil {
  1363  								if isFatalError(err, uo.Flags) {
  1364  									return err
  1365  								}
  1366  								errUnmarshal = cmp.Or(errUnmarshal, err)
  1367  							}
  1368  						}
  1369  						continue
  1370  					}
  1371  				}
  1372  				if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && !seenIdxs.insert(uint(f.id)) {
  1373  					// TODO: Unread the object name.
  1374  					return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val))
  1375  				}
  1376  
  1377  				// Process the object member value.
  1378  				unmarshal := f.fncs.unmarshal
  1379  				if uo.Unmarshalers != nil {
  1380  					unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, f.typ)
  1381  				}
  1382  				flagsOriginal := uo.Flags
  1383  				if f.string {
  1384  					uo.Flags.Set(jsonflags.StringTag | 1)
  1385  				}
  1386  				if f.format != "" {
  1387  					uo.Flags.Set(jsonflags.FormatTag | 1)
  1388  					uo.Format = f.format
  1389  				}
  1390  				v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable
  1391  				if len(f.index) > 0 {
  1392  					v = v.fieldByIndex(f.index, true)
  1393  					if !v.IsValid() {
  1394  						err := newUnmarshalErrorBefore(dec, t, errNilField)
  1395  						if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1396  							return err
  1397  						}
  1398  						errUnmarshal = cmp.Or(errUnmarshal, err)
  1399  						unmarshal = func(dec *jsontext.Decoder, _ addressableValue, _ *jsonopts.Struct) error {
  1400  							return dec.SkipValue()
  1401  						}
  1402  					}
  1403  				}
  1404  				err = unmarshal(dec, v, uo)
  1405  				uo.Flags = flagsOriginal
  1406  				uo.Format = ""
  1407  				if err != nil {
  1408  					if isFatalError(err, uo.Flags) {
  1409  						return err
  1410  					}
  1411  					errUnmarshal = cmp.Or(errUnmarshal, err)
  1412  				}
  1413  			}
  1414  			if _, err := dec.ReadToken(); err != nil {
  1415  				return err
  1416  			}
  1417  			return errUnmarshal
  1418  		}
  1419  		return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
  1420  	}
  1421  	return &fncs
  1422  }
  1423  
  1424  func (va addressableValue) fieldByIndex(index []int, mayAlloc bool) addressableValue {
  1425  	for _, i := range index {
  1426  		va = va.indirect(mayAlloc)
  1427  		if !va.IsValid() {
  1428  			return va
  1429  		}
  1430  		va = addressableValue{va.Field(i), va.forcedAddr} // addressable if struct value is addressable
  1431  	}
  1432  	return va
  1433  }
  1434  
  1435  func (va addressableValue) indirect(mayAlloc bool) addressableValue {
  1436  	if va.Kind() == reflect.Pointer {
  1437  		if va.IsNil() {
  1438  			if !mayAlloc || !va.CanSet() {
  1439  				return addressableValue{}
  1440  			}
  1441  			va.Set(reflect.New(va.Type().Elem()))
  1442  		}
  1443  		va = addressableValue{va.Elem(), false} // dereferenced pointer is always addressable
  1444  	}
  1445  	return va
  1446  }
  1447  
  1448  // isLegacyEmpty reports whether a value is empty according to the v1 definition.
  1449  func isLegacyEmpty(v addressableValue) bool {
  1450  	// Equivalent to encoding/json.isEmptyValue@v1.21.0.
  1451  	switch v.Kind() {
  1452  	case reflect.Bool:
  1453  		return v.Bool() == false
  1454  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1455  		return v.Int() == 0
  1456  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1457  		return v.Uint() == 0
  1458  	case reflect.Float32, reflect.Float64:
  1459  		return v.Float() == 0
  1460  	case reflect.String, reflect.Map, reflect.Slice, reflect.Array:
  1461  		return v.Len() == 0
  1462  	case reflect.Pointer, reflect.Interface:
  1463  		return v.IsNil()
  1464  	}
  1465  	return false
  1466  }
  1467  
  1468  func makeSliceArshaler(t reflect.Type) *arshaler {
  1469  	var fncs arshaler
  1470  	var (
  1471  		once    sync.Once
  1472  		valFncs *arshaler
  1473  	)
  1474  	init := func() {
  1475  		valFncs = lookupArshaler(t.Elem())
  1476  	}
  1477  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
  1478  		// Check for cycles.
  1479  		xe := export.Encoder(enc)
  1480  		if xe.Tokens.Depth() > startDetectingCyclesAfter {
  1481  			if err := visitPointer(&xe.SeenPointers, va.Value); err != nil {
  1482  				return newMarshalErrorBefore(enc, t, err)
  1483  			}
  1484  			defer leavePointer(&xe.SeenPointers, va.Value)
  1485  		}
  1486  
  1487  		emitNull := mo.Flags.Get(jsonflags.FormatNilSliceAsNull)
  1488  		if mo.Flags.Has(jsonflags.TagFlags) {
  1489  			if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1490  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
  1491  			}
  1492  			if mo.Flags.Has(jsonflags.FormatTag) {
  1493  				switch mo.Format {
  1494  				case "emitnull":
  1495  					emitNull = true
  1496  				case "emitempty":
  1497  					emitNull = false
  1498  				default:
  1499  					return newInvalidFormatError(enc, t)
  1500  				}
  1501  			}
  1502  		}
  1503  
  1504  		// Handle empty slices.
  1505  		n := va.Len()
  1506  		if n == 0 {
  1507  			if emitNull && va.IsNil() {
  1508  				return enc.WriteToken(jsontext.Null)
  1509  			}
  1510  			// Optimize for marshaling an empty slice without any preceding whitespace.
  1511  			if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() {
  1512  				xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '['), "[]"...)
  1513  				xe.Tokens.Last.Increment()
  1514  				if xe.NeedFlush() {
  1515  					return xe.Flush()
  1516  				}
  1517  				return nil
  1518  			}
  1519  		}
  1520  
  1521  		once.Do(init)
  1522  		if err := enc.WriteToken(jsontext.BeginArray); err != nil {
  1523  			return err
  1524  		}
  1525  		marshal := valFncs.marshal
  1526  		if mo.Marshalers != nil {
  1527  			marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem())
  1528  		}
  1529  		for i := range n {
  1530  			v := addressableValue{va.Index(i), false} // indexed slice element is always addressable
  1531  			if err := marshal(enc, v, mo); err != nil {
  1532  				return err
  1533  			}
  1534  		}
  1535  		if err := enc.WriteToken(jsontext.EndArray); err != nil {
  1536  			return err
  1537  		}
  1538  		return nil
  1539  	}
  1540  	emptySlice := reflect.MakeSlice(t, 0, 0)
  1541  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1542  		if uo.Flags.Has(jsonflags.TagFlags) {
  1543  			if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1544  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
  1545  			}
  1546  			if uo.Flags.Has(jsonflags.FormatTag) {
  1547  				switch uo.Format {
  1548  				case "emitnull", "emitempty":
  1549  				default:
  1550  					return newInvalidFormatError(dec, t)
  1551  				}
  1552  			}
  1553  		}
  1554  
  1555  		tok, err := dec.ReadToken()
  1556  		if err != nil {
  1557  			return err
  1558  		}
  1559  		k := tok.Kind()
  1560  		switch k {
  1561  		case 'n':
  1562  			va.SetZero()
  1563  			return nil
  1564  		case '[':
  1565  			once.Do(init)
  1566  			unmarshal := valFncs.unmarshal
  1567  			if uo.Unmarshalers != nil {
  1568  				unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem())
  1569  			}
  1570  			mustZero := true // we do not know the cleanliness of unused capacity
  1571  			cap := va.Cap()
  1572  			if cap > 0 {
  1573  				va.SetLen(cap)
  1574  			}
  1575  			var i int
  1576  			var errUnmarshal error
  1577  			for dec.PeekKind() != ']' {
  1578  				if i == cap {
  1579  					va.Value.Grow(1)
  1580  					cap = va.Cap()
  1581  					va.SetLen(cap)
  1582  					mustZero = false // reflect.Value.Grow ensures new capacity is zero-initialized
  1583  				}
  1584  				v := addressableValue{va.Index(i), false} // indexed slice element is always addressable
  1585  				i++
  1586  				if mustZero && !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
  1587  					v.SetZero()
  1588  				}
  1589  				if err := unmarshal(dec, v, uo); err != nil {
  1590  					if isFatalError(err, uo.Flags) {
  1591  						va.SetLen(i)
  1592  						return err
  1593  					}
  1594  					errUnmarshal = cmp.Or(errUnmarshal, err)
  1595  				}
  1596  			}
  1597  			if i == 0 {
  1598  				va.Set(emptySlice)
  1599  			} else {
  1600  				va.SetLen(i)
  1601  			}
  1602  			if _, err := dec.ReadToken(); err != nil {
  1603  				return err
  1604  			}
  1605  			return errUnmarshal
  1606  		}
  1607  		return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
  1608  	}
  1609  	return &fncs
  1610  }
  1611  
  1612  var errArrayUnderflow = errors.New("too few array elements")
  1613  var errArrayOverflow = errors.New("too many array elements")
  1614  
  1615  func makeArrayArshaler(t reflect.Type) *arshaler {
  1616  	var fncs arshaler
  1617  	var (
  1618  		once    sync.Once
  1619  		valFncs *arshaler
  1620  	)
  1621  	init := func() {
  1622  		valFncs = lookupArshaler(t.Elem())
  1623  	}
  1624  	n := t.Len()
  1625  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
  1626  		if mo.Flags.Has(jsonflags.TagFlags) {
  1627  			if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1628  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
  1629  			}
  1630  			if mo.Flags.Has(jsonflags.FormatTag) {
  1631  				return newInvalidFormatError(enc, t)
  1632  			}
  1633  		}
  1634  		once.Do(init)
  1635  		if err := enc.WriteToken(jsontext.BeginArray); err != nil {
  1636  			return err
  1637  		}
  1638  		marshal := valFncs.marshal
  1639  		if mo.Marshalers != nil {
  1640  			marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem())
  1641  		}
  1642  		for i := range n {
  1643  			v := addressableValue{va.Index(i), va.forcedAddr} // indexed array element is addressable if array is addressable
  1644  			if err := marshal(enc, v, mo); err != nil {
  1645  				return err
  1646  			}
  1647  		}
  1648  		if err := enc.WriteToken(jsontext.EndArray); err != nil {
  1649  			return err
  1650  		}
  1651  		return nil
  1652  	}
  1653  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1654  		if uo.Flags.Has(jsonflags.TagFlags) {
  1655  			if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1656  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
  1657  			}
  1658  			if uo.Flags.Has(jsonflags.FormatTag) {
  1659  				return newInvalidFormatError(dec, t)
  1660  			}
  1661  		}
  1662  		tok, err := dec.ReadToken()
  1663  		if err != nil {
  1664  			return err
  1665  		}
  1666  		k := tok.Kind()
  1667  		switch k {
  1668  		case 'n':
  1669  			if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
  1670  				va.SetZero()
  1671  			}
  1672  			return nil
  1673  		case '[':
  1674  			once.Do(init)
  1675  			unmarshal := valFncs.unmarshal
  1676  			if uo.Unmarshalers != nil {
  1677  				unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem())
  1678  			}
  1679  			var i int
  1680  			var errUnmarshal error
  1681  			for dec.PeekKind() != ']' {
  1682  				if i >= n {
  1683  					if err := dec.SkipValue(); err != nil {
  1684  						return err
  1685  					}
  1686  					err = errArrayOverflow
  1687  					continue
  1688  				}
  1689  				v := addressableValue{va.Index(i), va.forcedAddr} // indexed array element is addressable if array is addressable
  1690  				if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
  1691  					v.SetZero()
  1692  				}
  1693  				if err := unmarshal(dec, v, uo); err != nil {
  1694  					if isFatalError(err, uo.Flags) {
  1695  						return err
  1696  					}
  1697  					errUnmarshal = cmp.Or(errUnmarshal, err)
  1698  				}
  1699  				i++
  1700  			}
  1701  			for ; i < n; i++ {
  1702  				va.Index(i).SetZero()
  1703  				err = errArrayUnderflow
  1704  			}
  1705  			if _, err := dec.ReadToken(); err != nil {
  1706  				return err
  1707  			}
  1708  			if err != nil && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) {
  1709  				return newUnmarshalErrorAfter(dec, t, err)
  1710  			}
  1711  			return errUnmarshal
  1712  		}
  1713  		return newUnmarshalErrorAfterWithSkipping(dec, t, nil)
  1714  	}
  1715  	return &fncs
  1716  }
  1717  
  1718  func makePointerArshaler(t reflect.Type) *arshaler {
  1719  	var fncs arshaler
  1720  	var (
  1721  		once    sync.Once
  1722  		valFncs *arshaler
  1723  	)
  1724  	init := func() {
  1725  		valFncs = lookupArshaler(t.Elem())
  1726  	}
  1727  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
  1728  		// Check for cycles.
  1729  		xe := export.Encoder(enc)
  1730  		if xe.Tokens.Depth() > startDetectingCyclesAfter {
  1731  			if err := visitPointer(&xe.SeenPointers, va.Value); err != nil {
  1732  				return newMarshalErrorBefore(enc, t, err)
  1733  			}
  1734  			defer leavePointer(&xe.SeenPointers, va.Value)
  1735  		}
  1736  
  1737  		// NOTE: Struct.Format is forwarded to underlying marshal.
  1738  		if mo.Flags.Get(jsonflags.StringTag) && mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && t.Elem().Kind() == reflect.Pointer {
  1739  			if !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1740  				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
  1741  			}
  1742  			mo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to nested pointers
  1743  		}
  1744  		if va.IsNil() {
  1745  			return enc.WriteToken(jsontext.Null)
  1746  		}
  1747  		once.Do(init)
  1748  		marshal := valFncs.marshal
  1749  		if mo.Marshalers != nil {
  1750  			marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem())
  1751  		}
  1752  		v := addressableValue{va.Elem(), false} // dereferenced pointer is always addressable
  1753  		return marshal(enc, v, mo)
  1754  	}
  1755  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1756  		// NOTE: Struct.Format is forwarded to underlying unmarshal.
  1757  		if dec.PeekKind() == 'n' {
  1758  			if _, err := dec.ReadToken(); err != nil {
  1759  				return err
  1760  			}
  1761  			va.SetZero()
  1762  			return nil
  1763  		}
  1764  		if uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && t.Elem().Kind() == reflect.Pointer {
  1765  			if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1766  				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
  1767  			}
  1768  			uo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to nested pointers
  1769  		}
  1770  		once.Do(init)
  1771  		unmarshal := valFncs.unmarshal
  1772  		if uo.Unmarshalers != nil {
  1773  			unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem())
  1774  		}
  1775  		if va.IsNil() {
  1776  			va.Set(reflect.New(t.Elem()))
  1777  		}
  1778  		v := addressableValue{va.Elem(), false} // dereferenced pointer is always addressable
  1779  		if err := unmarshal(dec, v, uo); err != nil {
  1780  			return err
  1781  		}
  1782  		if uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
  1783  			// A JSON null quoted within a JSON string should take effect
  1784  			// within the pointer value, rather than the indirect value.
  1785  			//
  1786  			// TODO: This does not correctly handle escaped nulls
  1787  			// (e.g., "\u006e\u0075\u006c\u006c"), but is good enough
  1788  			// for such an esoteric use case of the `string` option.
  1789  			if string(export.Decoder(dec).PreviousTokenOrValue()) == `"null"` {
  1790  				va.SetZero()
  1791  			}
  1792  		}
  1793  		return nil
  1794  	}
  1795  	return &fncs
  1796  }
  1797  
  1798  func makeInterfaceArshaler(t reflect.Type) *arshaler {
  1799  	// NOTE: Values retrieved from an interface are not addressable,
  1800  	// so we shallow copy the values to make them addressable and
  1801  	// store them back into the interface afterwards.
  1802  
  1803  	var fncs arshaler
  1804  	var whichMarshaler reflect.Type
  1805  	for _, iface := range allMarshalerTypes {
  1806  		if t.Implements(iface) {
  1807  			whichMarshaler = t
  1808  			break
  1809  		}
  1810  	}
  1811  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
  1812  		if mo.Flags.Has(jsonflags.TagFlags) {
  1813  			if mo.Flags.Get(jsonflags.StringTag) {
  1814  				if !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1815  					return newMarshalErrorBefore(enc, t, errInvalidStringTag)
  1816  				}
  1817  				if mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
  1818  					mo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to interface types
  1819  				}
  1820  			}
  1821  			if mo.Flags.Has(jsonflags.FormatTag) {
  1822  				return newInvalidFormatError(enc, t)
  1823  			}
  1824  		}
  1825  		if va.IsNil() {
  1826  			return enc.WriteToken(jsontext.Null)
  1827  		} else if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && whichMarshaler != nil {
  1828  			// The marshaler for a pointer never calls the method on a nil receiver.
  1829  			// Wrap the nil pointer within a struct type so that marshal
  1830  			// instead appears on a value receiver and may be called.
  1831  			if va.Elem().Kind() == reflect.Pointer && va.Elem().IsNil() {
  1832  				v2 := newAddressableValue(whichMarshaler)
  1833  				switch whichMarshaler {
  1834  				case jsonMarshalerToType:
  1835  					v2.Set(reflect.ValueOf(struct{ MarshalerTo }{va.Elem().Interface().(MarshalerTo)}))
  1836  				case jsonMarshalerType:
  1837  					v2.Set(reflect.ValueOf(struct{ Marshaler }{va.Elem().Interface().(Marshaler)}))
  1838  				case textAppenderType:
  1839  					v2.Set(reflect.ValueOf(struct{ encoding.TextAppender }{va.Elem().Interface().(encoding.TextAppender)}))
  1840  				case textMarshalerType:
  1841  					v2.Set(reflect.ValueOf(struct{ encoding.TextMarshaler }{va.Elem().Interface().(encoding.TextMarshaler)}))
  1842  				}
  1843  				va = v2
  1844  			}
  1845  		}
  1846  		v := newAddressableValue(va.Elem().Type())
  1847  		v.Set(va.Elem())
  1848  		marshal := lookupArshaler(v.Type()).marshal
  1849  		if mo.Marshalers != nil {
  1850  			marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type())
  1851  		}
  1852  		// Optimize for the any type if there are no special options.
  1853  		if optimizeCommon &&
  1854  			t == anyType && !mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.TagFlags) &&
  1855  			(mo.Marshalers == nil || !mo.Marshalers.(*Marshalers).fromAny) {
  1856  			return marshalValueAny(enc, va.Elem().Interface(), mo)
  1857  		}
  1858  		return marshal(enc, v, mo)
  1859  	}
  1860  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1861  		if uo.Flags.Has(jsonflags.TagFlags) {
  1862  			if uo.Flags.Get(jsonflags.StringTag) {
  1863  				if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1864  					return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
  1865  				}
  1866  				if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) {
  1867  					uo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to interface types
  1868  				}
  1869  			}
  1870  			if uo.Flags.Has(jsonflags.FormatTag) {
  1871  				return newInvalidFormatError(dec, t)
  1872  			}
  1873  		}
  1874  		if uo.Flags.Get(jsonflags.MergeWithLegacySemantics) && !va.IsNil() {
  1875  			// Legacy merge behavior is difficult to explain.
  1876  			// In general, it only merges for non-nil pointer kinds.
  1877  			// As a special case, unmarshaling a JSON null into a pointer
  1878  			// sets a concrete nil pointer of the underlying type
  1879  			// (rather than setting the interface value itself to nil).
  1880  			e := va.Elem()
  1881  			if e.Kind() == reflect.Pointer && !e.IsNil() {
  1882  				if dec.PeekKind() == 'n' && e.Elem().Kind() == reflect.Pointer {
  1883  					if _, err := dec.ReadToken(); err != nil {
  1884  						return err
  1885  					}
  1886  					va.Elem().Elem().SetZero()
  1887  					return nil
  1888  				}
  1889  			} else {
  1890  				va.SetZero()
  1891  			}
  1892  		}
  1893  		if dec.PeekKind() == 'n' {
  1894  			if _, err := dec.ReadToken(); err != nil {
  1895  				return err
  1896  			}
  1897  			va.SetZero()
  1898  			return nil
  1899  		}
  1900  		var v addressableValue
  1901  		if va.IsNil() {
  1902  			// Optimize for the any type if there are no special options.
  1903  			// We do not care about stringified numbers since JSON strings
  1904  			// are always unmarshaled into an any value as Go strings.
  1905  			// Duplicate name check must be enforced since unmarshalValueAny
  1906  			// does not implement merge semantics.
  1907  			if optimizeCommon &&
  1908  				t == anyType && !uo.Flags.Get(jsonflags.AllowDuplicateNames|jsonflags.FormatTag) &&
  1909  				(uo.Unmarshalers == nil || !uo.Unmarshalers.(*Unmarshalers).fromAny) {
  1910  				v, err := unmarshalValueAny(dec, uo)
  1911  				// We must check for nil interface values up front.
  1912  				// See https://go.dev/issue/52310.
  1913  				if v != nil {
  1914  					va.Set(reflect.ValueOf(v))
  1915  				}
  1916  				return err
  1917  			}
  1918  
  1919  			k := dec.PeekKind()
  1920  			if !isAnyType(t) {
  1921  				return newUnmarshalErrorBeforeWithSkipping(dec, t, internal.ErrNilInterface)
  1922  			}
  1923  			switch k {
  1924  			case 'f', 't':
  1925  				v = newAddressableValue(boolType)
  1926  			case '"':
  1927  				v = newAddressableValue(stringType)
  1928  			case '0':
  1929  				if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
  1930  					v = addressableValue{reflect.ValueOf(internal.NewRawNumber()).Elem(), true}
  1931  				} else {
  1932  					v = newAddressableValue(float64Type)
  1933  				}
  1934  			case '{':
  1935  				v = newAddressableValue(mapStringAnyType)
  1936  			case '[':
  1937  				v = newAddressableValue(sliceAnyType)
  1938  			default:
  1939  				// If k is invalid (e.g., due to an I/O or syntax error), then
  1940  				// that will be cached by PeekKind and returned by ReadValue.
  1941  				// If k is '}' or ']', then ReadValue must error since
  1942  				// those are invalid kinds at the start of a JSON value.
  1943  				_, err := dec.ReadValue()
  1944  				return err
  1945  			}
  1946  		} else {
  1947  			// Shallow copy the existing value to keep it addressable.
  1948  			// Any mutations at the top-level of the value will be observable
  1949  			// since we always store this value back into the interface value.
  1950  			v = newAddressableValue(va.Elem().Type())
  1951  			v.Set(va.Elem())
  1952  		}
  1953  		unmarshal := lookupArshaler(v.Type()).unmarshal
  1954  		if uo.Unmarshalers != nil {
  1955  			unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, v.Type())
  1956  		}
  1957  		err := unmarshal(dec, v, uo)
  1958  		va.Set(v.Value)
  1959  		return err
  1960  	}
  1961  	return &fncs
  1962  }
  1963  
  1964  // isAnyType reports whether t is equivalent to the any interface type.
  1965  func isAnyType(t reflect.Type) bool {
  1966  	// This is forward compatible if the Go language permits type sets within
  1967  	// ordinary interfaces where an interface with zero methods does not
  1968  	// necessarily mean it can hold every possible Go type.
  1969  	// See https://go.dev/issue/45346.
  1970  	return t == anyType || anyType.Implements(t)
  1971  }
  1972  
  1973  func makeInvalidArshaler(t reflect.Type) *arshaler {
  1974  	var fncs arshaler
  1975  	fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
  1976  		return newMarshalErrorBefore(enc, t, nil)
  1977  	}
  1978  	fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
  1979  		// Under legacy error semantics, unmarshal continues on even with errors.
  1980  		// Thus, always consume the value first.
  1981  		// As a special-case, null is permitted for unsupported types.
  1982  		if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
  1983  			switch val, err := dec.ReadValue(); {
  1984  			case err != nil:
  1985  				return err
  1986  			case val.Kind() == 'n':
  1987  				return nil
  1988  			default:
  1989  				return newUnmarshalErrorAfter(dec, t, nil)
  1990  			}
  1991  		}
  1992  		return newUnmarshalErrorBefore(dec, t, nil)
  1993  	}
  1994  	return &fncs
  1995  }
  1996  
  1997  func stringOrNumberKind(isString bool) jsontext.Kind {
  1998  	if isString {
  1999  		return '"'
  2000  	} else {
  2001  		return '0'
  2002  	}
  2003  }
  2004  
  2005  type uintSet64 uint64
  2006  
  2007  func (s uintSet64) has(i uint) bool { return s&(1<<i) > 0 }
  2008  func (s *uintSet64) set(i uint)     { *s |= 1 << i }
  2009  
  2010  // uintSet is a set of unsigned integers.
  2011  // It is optimized for most integers being close to zero.
  2012  type uintSet struct {
  2013  	lo uintSet64
  2014  	hi []uintSet64
  2015  }
  2016  
  2017  // has reports whether i is in the set.
  2018  func (s *uintSet) has(i uint) bool {
  2019  	if i < 64 {
  2020  		return s.lo.has(i)
  2021  	} else {
  2022  		i -= 64
  2023  		iHi, iLo := int(i/64), i%64
  2024  		return iHi < len(s.hi) && s.hi[iHi].has(iLo)
  2025  	}
  2026  }
  2027  
  2028  // insert inserts i into the set and reports whether it was the first insertion.
  2029  func (s *uintSet) insert(i uint) bool {
  2030  	// TODO: Make this inlinable at least for the lower 64-bit case.
  2031  	if i < 64 {
  2032  		has := s.lo.has(i)
  2033  		s.lo.set(i)
  2034  		return !has
  2035  	} else {
  2036  		i -= 64
  2037  		iHi, iLo := int(i/64), i%64
  2038  		if iHi >= len(s.hi) {
  2039  			s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...)
  2040  			s.hi = s.hi[:cap(s.hi)]
  2041  		}
  2042  		has := s.hi[iHi].has(iLo)
  2043  		s.hi[iHi].set(iLo)
  2044  		return !has
  2045  	}
  2046  }
  2047  

View as plain text