aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json/v2
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2025-10-06 12:56:29 -0700
committerJoseph Tsai <joetsai@digital-static.net>2025-10-10 18:03:36 -0700
commitb497a29d25b0f6f29bedaa92ac1d40a1ee5c0956 (patch)
tree07ed48d5f97abb6ef8e9de1fc48e12fbc1f7ac96 /src/encoding/json/v2
parent48bb7a61147c397d0f45c10bc21ba12fa9cec0ad (diff)
downloadgo-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.go51
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 {