src/encoding/json/decode.go | 6 +++--- src/encoding/json/decode_test.go | 17 +++++++++++++++++ diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index 0b29249218a32b037ff9f26fd617d118142d3e1d..7d235087e60f4bb998e4c5e862f27990f1b59034 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -672,6 +672,7 @@ return nil } var mapElem reflect.Value + originalErrorContext := d.errorContext for { // Read opening " of string key or closing }. @@ -832,8 +833,7 @@ if d.opcode != scanObjectValue { return errPhase } - d.errorContext.Struct = "" - d.errorContext.Field = "" + d.errorContext = originalErrorContext } return nil } @@ -991,7 +991,7 @@ } if fromQuoted { 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: n, err := d.convertNumber(s) if err != nil { diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go index ab83b81bb39584411ce0b5e260f04d1b8e77f26a..5746ddf9861e7e1f672ad92a5b6479331b868aa9 100644 --- a/src/encoding/json/decode_test.go +++ b/src/encoding/json/decode_test.go @@ -371,6 +371,10 @@ func (b *intWithPtrMarshalText) UnmarshalText(data []byte) error { return (*intWithMarshalText)(b).UnmarshalText(data) } +type mapStringToStringData struct { + Data map[string]string `json:"data"` +} + type unmarshalTest struct { in string ptr interface{} @@ -401,6 +405,7 @@ {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"}, {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, {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": 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), 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")}}, @@ -865,6 +870,18 @@ }`, ptr: new(Top), err: fmt.Errorf("json: unknown field \"extra\""), 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"}, }, }