Skip to content

Commit 92ae524

Browse files
bigfloodkatiehockman
authored andcommitted
[release-branch.go1.11] encoding/json: fix UnmarshalTypeError without field and struct values
Updates #26444 Updates #27275 Fixes #27318 Change-Id: I9e8cbff79f7643ca8964c572c1a98172b6831730 GitHub-Last-Rev: 7eea215 GitHub-Pull-Request: #26719 Reviewed-on: https://go-review.googlesource.com/126897 Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-on: https://go-review.googlesource.com/138178 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
1 parent 307f8b5 commit 92ae524

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/encoding/json/decode.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ func (d *decodeState) object(v reflect.Value) error {
672672
}
673673

674674
var mapElem reflect.Value
675+
originalErrorContext := d.errorContext
675676

676677
for {
677678
// Read opening " of string key or closing }.
@@ -832,8 +833,7 @@ func (d *decodeState) object(v reflect.Value) error {
832833
return errPhase
833834
}
834835

835-
d.errorContext.Struct = ""
836-
d.errorContext.Field = ""
836+
d.errorContext = originalErrorContext
837837
}
838838
return nil
839839
}
@@ -991,7 +991,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
991991
if fromQuoted {
992992
return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
993993
}
994-
return &UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}
994+
d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
995995
case reflect.Interface:
996996
n, err := d.convertNumber(s)
997997
if err != nil {

src/encoding/json/decode_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error {
371371
return (*intWithMarshalText)(b).UnmarshalText(data)
372372
}
373373

374+
type mapStringToStringData struct {
375+
Data map[string]string `json:"data"`
376+
}
377+
374378
type unmarshalTest struct {
375379
in string
376380
ptr interface{}
@@ -401,6 +405,7 @@ var unmarshalTests = []unmarshalTest{
401405
{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
402406
{in: "null", ptr: new(interface{}), out: nil},
403407
{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7, "T", "X"}},
408+
{in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeOf(""), 8, "T", "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}},
404409
{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
405410
{in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true},
406411
{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
@@ -866,6 +871,18 @@ var unmarshalTests = []unmarshalTest{
866871
err: fmt.Errorf("json: unknown field \"extra\""),
867872
disallowUnknownFields: true,
868873
},
874+
// issue 26444
875+
// UnmarshalTypeError without field & struct values
876+
{
877+
in: `{"data":{"test1": "bob", "test2": 123}}`,
878+
ptr: new(mapStringToStringData),
879+
err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 37, Struct: "mapStringToStringData", Field: "data"},
880+
},
881+
{
882+
in: `{"data":{"test1": 123, "test2": "bob"}}`,
883+
ptr: new(mapStringToStringData),
884+
err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 21, Struct: "mapStringToStringData", Field: "data"},
885+
},
869886
}
870887

871888
func TestMarshal(t *testing.T) {

0 commit comments

Comments
 (0)