[go] encoding/json: fix Unmarshal of value assigned to an interface variable.

5 views
Skip to first unread message

Dennis Gloss (Gerrit)

unread,
Oct 14, 2024, 8:20:25 AM10/14/24
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Dennis Gloss has uploaded the change for review

Commit message

encoding/json: fix Unmarshal of value assigned to an interface variable.

When I assign a variable to an interface variable,
the json.Unmarshal will convert it to map[string]any instead of
filling out the underlying variable.
E.g.
var p string
var i any = p

_ = json.Unmarshal([]byte(`{"x":1}`), &i)
fmt.Println(reflect.TypeOf(i))

This will print map[string]interface{}
Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa

Change diff

diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go
index 1a05ef5..37aed4d 100644
--- a/src/encoding/json/decode.go
+++ b/src/encoding/json/decode.go
@@ -613,15 +613,26 @@
return nil
}
v = pv
- t := v.Type()
-
// Decoding into nil interface? Switch to non-reflect code.
- if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
- oi := d.objectInterface()
- v.Set(reflect.ValueOf(oi))
- return nil
+ // If the interface is not nil, replace it with the underlying value
+ // and set the interface with that value in the end.
+ var iReplace bool
+ if v.Kind() == reflect.Interface {
+ if v.IsNil() {
+ if v.NumMethod() == 0 {
+ oi := d.objectInterface()
+ v.Set(reflect.ValueOf(oi))
+ return nil
+ }
+ } else {
+ el := v.Elem()
+ v = reflect.New(el.Type()).Elem()
+ iReplace = true
+ }
}

+ t := v.Type()
+
var fields structFields

// Check type of target:
@@ -828,6 +839,9 @@
panic(phasePanicMsg)
}
}
+ if iReplace {
+ pv.Set(v)
+ }
return nil
}

diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go
index 71895a9..c82e17c 100644
--- a/src/encoding/json/decode_test.go
+++ b/src/encoding/json/decode_test.go
@@ -1271,6 +1271,27 @@
}
}

+func TestUnmarshalAssignToInterface(t *testing.T) {
+ type Z struct {
+ Y int
+ }
+ var u Z
+ var i any = u
+ err := Unmarshal([]byte(`{"Y":1}`), &i)
+ if err != nil {
+ panic(err)
+ }
+ u, ok := i.(Z)
+ if !ok {
+ t.Errorf("wrong type of value, expected U, got=%s", reflect.TypeOf(i))
+ } else {
+ if u.Y != 1 {
+ t.Errorf("failed to unmarshal")
+ }
+ }
+
+}
+
// Independent of Decode, basic coverage of the accessors in Number
func TestNumberAccessors(t *testing.T) {
tests := []struct {
@@ -2497,9 +2518,9 @@
var v any
v = &v
data := []byte(`{"a": "b"}`)
-
- if err := Unmarshal(data, v); err != nil {
- t.Fatalf("Unmarshal error: %v", err)
+ err := Unmarshal(data, v)
+ if err == nil {
+ t.Fatalf("unexpected error: %v", err)
}
}

Change information

Files:
  • M src/encoding/json/decode.go
  • M src/encoding/json/decode_test.go
Change size: M
Delta: 2 files changed, 44 insertions(+), 9 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
Gerrit-Change-Number: 619995
Gerrit-PatchSet: 1
Gerrit-Owner: Dennis Gloss <dennis...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Dennis Gloss (Gerrit)

unread,
Oct 14, 2024, 8:47:29 AM10/14/24
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Russ Cox

Dennis Gloss uploaded new patchset

Dennis Gloss uploaded patch set #2 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Russ Cox
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
Gerrit-Change-Number: 619995
Gerrit-PatchSet: 2
Gerrit-Owner: Dennis Gloss <dennis...@gmail.com>
Gerrit-Reviewer: Russ Cox <r...@golang.org>
Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
Gerrit-CC: Gopher Robot <go...@golang.org>
Gerrit-CC: Joseph Tsai <joe...@digital-static.net>
Gerrit-Attention: Russ Cox <r...@golang.org>
unsatisfied_requirement
satisfied_requirement
open
diffy

Dennis Gloss (Gerrit)

unread,
Oct 14, 2024, 8:57:58 AM10/14/24
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Russ Cox

Dennis Gloss uploaded new patchset

Dennis Gloss uploaded patch set #3 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Russ Cox
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
Gerrit-Change-Number: 619995
Gerrit-PatchSet: 3
unsatisfied_requirement
satisfied_requirement
open
diffy

Dennis Gloss (Gerrit)

unread,
Oct 14, 2024, 2:19:31 PM10/14/24
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Russ Cox

Dennis Gloss uploaded new patchset

Dennis Gloss uploaded patch set #4 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Russ Cox
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
Gerrit-Change-Number: 619995
Gerrit-PatchSet: 4
unsatisfied_requirement
satisfied_requirement
open
diffy

Joseph Tsai (Gerrit)

unread,
Oct 14, 2024, 2:22:16 PM10/14/24
to Dennis Gloss, goph...@pubsubhelper.golang.org, Russ Cox, Brad Fitzpatrick, Daniel Martí, Gopher Robot, golang-co...@googlegroups.com
Attention needed from Dennis Gloss and Russ Cox

Joseph Tsai added 1 comment

Patchset-level comments
File-level comment, Patchset 4 (Latest):
Joseph Tsai . unresolved

This is a known issue, and unfortunately I don't think we can change this behavior in v1.

Open in Gerrit

Related details

Attention is currently required from:
  • Dennis Gloss
  • Russ Cox
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
    Gerrit-Change-Number: 619995
    Gerrit-PatchSet: 4
    Gerrit-Owner: Dennis Gloss <dennis...@gmail.com>
    Gerrit-Reviewer: Russ Cox <r...@golang.org>
    Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-CC: Joseph Tsai <joe...@digital-static.net>
    Gerrit-Attention: Dennis Gloss <dennis...@gmail.com>
    Gerrit-Attention: Russ Cox <r...@golang.org>
    Gerrit-Comment-Date: Mon, 14 Oct 2024 18:22:10 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    unsatisfied_requirement
    open
    diffy

    Dennis Gloss (Gerrit)

    unread,
    Oct 14, 2024, 3:07:58 PM10/14/24
    to goph...@pubsubhelper.golang.org, Russ Cox, Joseph Tsai, Brad Fitzpatrick, Daniel Martí, Gopher Robot, golang-co...@googlegroups.com
    Attention needed from Joseph Tsai and Russ Cox

    Dennis Gloss added 1 comment

    Patchset-level comments
    Joseph Tsai . unresolved

    This is a known issue, and unfortunately I don't think we can change this behavior in v1.

    Dennis Gloss

    I don't think anyone would use an interface variable assigned to a struct instance so that the variable would only be transformed into a map after Unmarshal. But otherwise I don't see any break of compatibility.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Joseph Tsai
    • Russ Cox
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
    Gerrit-Change-Number: 619995
    Gerrit-PatchSet: 4
    Gerrit-Owner: Dennis Gloss <dennis...@gmail.com>
    Gerrit-Reviewer: Russ Cox <r...@golang.org>
    Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-CC: Joseph Tsai <joe...@digital-static.net>
    Gerrit-Attention: Joseph Tsai <joe...@digital-static.net>
    Gerrit-Attention: Russ Cox <r...@golang.org>
    Gerrit-Comment-Date: Mon, 14 Oct 2024 19:07:51 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Joseph Tsai <joe...@digital-static.net>
    unsatisfied_requirement
    open
    diffy

    Dennis Gloss (Gerrit)

    unread,
    Oct 14, 2024, 5:29:03 PM10/14/24
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
    Attention needed from Joseph Tsai and Russ Cox

    Dennis Gloss uploaded new patchset

    Dennis Gloss uploaded patch set #5 to this change.
    Open in Gerrit

    Related details

    Attention is currently required from:
    • Joseph Tsai
    • Russ Cox
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: newpatchset
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
    Gerrit-Change-Number: 619995
    Gerrit-PatchSet: 5
    unsatisfied_requirement
    open
    diffy

    Dennis Gloss (Gerrit)

    unread,
    Oct 14, 2024, 5:32:05 PM10/14/24
    to goph...@pubsubhelper.golang.org, Russ Cox, Joseph Tsai, Brad Fitzpatrick, Daniel Martí, Gopher Robot, golang-co...@googlegroups.com
    Attention needed from Joseph Tsai and Russ Cox

    Dennis Gloss added 1 comment

    Patchset-level comments
    Joseph Tsai . unresolved

    This is a known issue, and unfortunately I don't think we can change this behavior in v1.

    Dennis Gloss

    I don't think anyone would use an interface variable assigned to a struct instance so that the variable would only be transformed into a map after Unmarshal. But otherwise I don't see any break of compatibility.

    Dennis Gloss

    As Alan Donovan pointed out, people reuse the `any` variable to unmarshal different types of json i.e. map, array, string. So I kept the old behavior for `any` type variables.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Joseph Tsai
    • Russ Cox
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I17e6dac73718081c9791ac02bb8fef711f6088aa
    Gerrit-Change-Number: 619995
    Gerrit-PatchSet: 5
    Gerrit-Owner: Dennis Gloss <dennis...@gmail.com>
    Gerrit-Reviewer: Russ Cox <r...@golang.org>
    Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-CC: Joseph Tsai <joe...@digital-static.net>
    Gerrit-Attention: Joseph Tsai <joe...@digital-static.net>
    Gerrit-Attention: Russ Cox <r...@golang.org>
    Gerrit-Comment-Date: Mon, 14 Oct 2024 21:31:58 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Joseph Tsai <joe...@digital-static.net>
    Comment-In-Reply-To: Dennis Gloss <dennis...@gmail.com>
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages