mirror of
https://github.com/golang/go
synced 2024-11-23 06:50:05 -07:00
encoding/json: fix decoding of types with '[]byte' as underlying type
All slice types which have elements of kind reflect.Uint8 are marshalled into base64 for compactness. When decoding such data into a custom type based on []byte the decoder checked the slice kind instead of the slice element kind, so no appropriate decoder was found. Fixed by letting the decoder check slice element kind like the encoder. This guarantees that already encoded data can still be successfully decoded. Fixes #8962. Change-Id: Ia320d4dc2c6e9e5fe6d8dc15788c81da23d20c4f Reviewed-on: https://go-review.googlesource.com/9371 Reviewed-by: Peter Waldschmidt <peter@waldschmidt.com> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
5726af54eb
commit
4302fd0409
@ -739,7 +739,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
|
|||||||
default:
|
default:
|
||||||
d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
|
d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
if v.Type() != byteSliceType {
|
if v.Type().Elem().Kind() != reflect.Uint8 {
|
||||||
d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
|
d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1207,7 +1207,28 @@ func TestStringKind(t *testing.T) {
|
|||||||
if !reflect.DeepEqual(m1, m2) {
|
if !reflect.DeepEqual(m1, m2) {
|
||||||
t.Error("Items should be equal after encoding and then decoding")
|
t.Error("Items should be equal after encoding and then decoding")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom types with []byte as underlying type could not be marshalled
|
||||||
|
// and then unmarshalled.
|
||||||
|
// Issue 8962.
|
||||||
|
func TestByteKind(t *testing.T) {
|
||||||
|
type byteKind []byte
|
||||||
|
|
||||||
|
a := byteKind("hello")
|
||||||
|
|
||||||
|
data, err := Marshal(a)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
var b byteKind
|
||||||
|
err = Unmarshal(data, &b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(a, b) {
|
||||||
|
t.Errorf("expected %v == %v", a, b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var decodeTypeErrorTests = []struct {
|
var decodeTypeErrorTests = []struct {
|
||||||
|
@ -275,8 +275,6 @@ func (e *encodeState) error(err error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var byteSliceType = reflect.TypeOf([]byte(nil))
|
|
||||||
|
|
||||||
func isEmptyValue(v reflect.Value) bool {
|
func isEmptyValue(v reflect.Value) bool {
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||||
|
Loading…
Reference in New Issue
Block a user