diff options
| author | Joe Tsai <joetsai@digital-static.net> | 2025-10-06 12:56:29 -0700 |
|---|---|---|
| committer | Joseph Tsai <joetsai@digital-static.net> | 2025-10-10 18:03:36 -0700 |
| commit | b497a29d25b0f6f29bedaa92ac1d40a1ee5c0956 (patch) | |
| tree | 07ed48d5f97abb6ef8e9de1fc48e12fbc1f7ac96 /src/encoding/json/v2 | |
| parent | 48bb7a61147c397d0f45c10bc21ba12fa9cec0ad (diff) | |
| download | go-b497a29d25b0f6f29bedaa92ac1d40a1ee5c0956.tar.xz | |
encoding/json: fix regression in quoted numbers under goexperiment.jsonv2
The legacy parsing of quoted numbers in v1 was according to
the Go grammar for a number, rather than
the JSON grammar for a number.
The former is a superset of the latter.
This is a historical mistake, but usages exist that depend on it.
We already have branches for StringifyWithLegacySemantics
to handle quoted nulls, so we can expand it to handle this.
Fixes #75619
Change-Id: Ic07802539b7cbe0e1f53bd0f7e9bb344a8447203
Reviewed-on: https://go-review.googlesource.com/c/go/+/709615
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Joseph Tsai <joetsai@digital-static.net>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/encoding/json/v2')
| -rw-r--r-- | src/encoding/json/v2/arshal_default.go | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/encoding/json/v2/arshal_default.go b/src/encoding/json/v2/arshal_default.go index c2307fa31d..078d345e14 100644 --- a/src/encoding/json/v2/arshal_default.go +++ b/src/encoding/json/v2/arshal_default.go @@ -474,10 +474,21 @@ func makeIntArshaler(t reflect.Type) *arshaler { break } val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { - if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { - va.SetInt(0) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + // For historical reasons, v1 parsed a quoted number + // according to the Go syntax and permitted a quoted null. + // See https://go.dev/issue/75619 + n, err := strconv.ParseInt(string(val), 10, bits) + if err != nil { + if string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetInt(0) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } + va.SetInt(n) return nil } fallthrough @@ -561,10 +572,21 @@ func makeUintArshaler(t reflect.Type) *arshaler { break } val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { - if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { - va.SetUint(0) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + // For historical reasons, v1 parsed a quoted number + // according to the Go syntax and permitted a quoted null. + // See https://go.dev/issue/75619 + n, err := strconv.ParseUint(string(val), 10, bits) + if err != nil { + if string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetUint(0) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } + va.SetUint(n) return nil } fallthrough @@ -671,10 +693,21 @@ func makeFloatArshaler(t reflect.Type) *arshaler { if !stringify { break } - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { - if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { - va.SetFloat(0) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + // For historical reasons, v1 parsed a quoted number + // according to the Go syntax and permitted a quoted null. + // See https://go.dev/issue/75619 + n, err := strconv.ParseFloat(string(val), bits) + if err != nil { + if string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetFloat(0) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } + va.SetFloat(n) return nil } if n, err := jsonwire.ConsumeNumber(val); n != len(val) || err != nil { |
