]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: fix decoding of types with '[]byte' as underlying type
authorHÃ¥vard Haugen <havard.haugen@gmail.com>
Sun, 26 Apr 2015 21:52:42 +0000 (23:52 +0200)
committerRuss Cox <rsc@golang.org>
Fri, 15 May 2015 16:26:53 +0000 (16:26 +0000)
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>
src/encoding/json/decode.go
src/encoding/json/decode_test.go
src/encoding/json/encode.go

index f26a7d49f00f98b23b1266e826216857dd436ac3..613641afbb44075224df4ff9dbc2a976bd67e29a 100644 (file)
@@ -739,7 +739,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
                default:
                        d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
                case reflect.Slice:
-                       if v.Type() != byteSliceType {
+                       if v.Type().Elem().Kind() != reflect.Uint8 {
                                d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
                                break
                        }
index 7ecc8f440225396b2e35df818c4e45d5523f9718..f208ee8a7cac5425455899aeb74dba8589300596 100644 (file)
@@ -1207,7 +1207,28 @@ func TestStringKind(t *testing.T) {
        if !reflect.DeepEqual(m1, m2) {
                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 {
index 4db9f35e6918964d1bcb478b0c5418a868c560fd..7789bb5141cbbf9735d21aef11158f2d8d3b5710 100644 (file)
@@ -275,8 +275,6 @@ func (e *encodeState) error(err error) {
        panic(err)
 }
 
-var byteSliceType = reflect.TypeOf([]byte(nil))
-
 func isEmptyValue(v reflect.Value) bool {
        switch v.Kind() {
        case reflect.Array, reflect.Map, reflect.Slice, reflect.String: