Commit 21e85c29 authored by Taesu Pyo's avatar Taesu Pyo Committed by Daniel Martí

encoding/json: fix UnmarshalTypeError without field and struct values

Fixes #26444
Fixes #27275

Change-Id: I9e8cbff79f7643ca8964c572c1a98172b6831730
GitHub-Last-Rev: 7eea2158b67ccab34b45a21e8f4289c36de02d93
GitHub-Pull-Request: golang/go#26719
Reviewed-on: https://go-review.googlesource.com/126897Reviewed-by: 's avatarDaniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 422151ad
...@@ -670,6 +670,7 @@ func (d *decodeState) object(v reflect.Value) error { ...@@ -670,6 +670,7 @@ func (d *decodeState) object(v reflect.Value) error {
} }
var mapElem reflect.Value var mapElem reflect.Value
originalErrorContext := d.errorContext
for { for {
// Read opening " of string key or closing }. // Read opening " of string key or closing }.
...@@ -829,8 +830,7 @@ func (d *decodeState) object(v reflect.Value) error { ...@@ -829,8 +830,7 @@ func (d *decodeState) object(v reflect.Value) error {
return errPhase return errPhase
} }
d.errorContext.Struct = nil d.errorContext = originalErrorContext
d.errorContext.Field = ""
} }
return nil return nil
} }
...@@ -988,7 +988,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool ...@@ -988,7 +988,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
if fromQuoted { if fromQuoted {
return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
} }
return &UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())} d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
case reflect.Interface: case reflect.Interface:
n, err := d.convertNumber(s) n, err := d.convertNumber(s)
if err != nil { if err != nil {
......
...@@ -371,6 +371,10 @@ func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error { ...@@ -371,6 +371,10 @@ func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error {
return (*intWithMarshalText)(b).UnmarshalText(data) return (*intWithMarshalText)(b).UnmarshalText(data)
} }
type mapStringToStringData struct {
Data map[string]string `json:"data"`
}
type unmarshalTest struct { type unmarshalTest struct {
in string in string
ptr interface{} ptr interface{}
...@@ -401,6 +405,7 @@ var unmarshalTests = []unmarshalTest{ ...@@ -401,6 +405,7 @@ var unmarshalTests = []unmarshalTest{
{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
{in: "null", ptr: new(interface{}), out: nil}, {in: "null", ptr: new(interface{}), out: nil},
{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7, "T", "X"}}, {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7, "T", "X"}},
{in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeOf(""), 8, "T", "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}},
{in: `{"x": 1}`, ptr: new(tx), out: tx{}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}},
{in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true}, {in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true},
{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, {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{ ...@@ -866,6 +871,18 @@ var unmarshalTests = []unmarshalTest{
err: fmt.Errorf("json: unknown field \"extra\""), err: fmt.Errorf("json: unknown field \"extra\""),
disallowUnknownFields: true, disallowUnknownFields: true,
}, },
// issue 26444
// UnmarshalTypeError without field & struct values
{
in: `{"data":{"test1": "bob", "test2": 123}}`,
ptr: new(mapStringToStringData),
err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 37, Struct: "mapStringToStringData", Field: "data"},
},
{
in: `{"data":{"test1": 123, "test2": "bob"}}`,
ptr: new(mapStringToStringData),
err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 21, Struct: "mapStringToStringData", Field: "data"},
},
} }
func TestMarshal(t *testing.T) { func TestMarshal(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment