]> Cypherpunks repositories - gostls13.git/commitdiff
json: unmarshal types that are byte slices.
authorPaul Borman <borman@google.com>
Fri, 12 Jul 2013 02:34:09 +0000 (22:34 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 12 Jul 2013 02:34:09 +0000 (22:34 -0400)
The json package cheerfully would marshal

        type S struct {
                IP net.IP
        }

but would give an error when unmarshalling.  This change allows any
type whose concrete type is a byte slice to be unmarshalled from a
string.

Fixes #5086.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/11161044

src/pkg/encoding/json/decode.go
src/pkg/encoding/json/decode_test.go
src/pkg/encoding/json/encode.go

index 62ac294b89f3bd113c6b63f6974a1c4f7d147dcb..e608ef4a61dc49d2a20719bdf1e37e224240c39a 100644 (file)
@@ -660,7 +660,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
                default:
                        d.saveError(&UnmarshalTypeError{"string", v.Type()})
                case reflect.Slice:
-                       if v.Type() != byteSliceType {
+                       if v.Type().Elem().Kind() != reflect.Uint8 {
                                d.saveError(&UnmarshalTypeError{"string", v.Type()})
                                break
                        }
index f845f69ab7f4e7bb0cbfc83a98d4a425c36593f9..97cbb4f09ba176e8d42527fef369df529382a62c 100644 (file)
@@ -1191,3 +1191,32 @@ func TestSkipArrayObjects(t *testing.T) {
                t.Errorf("got error %q, want nil", err)
        }
 }
+
+// Test that types of byte slices (such as net.IP) both
+// marshal and unmarshal.
+func TestByteSliceType(t *testing.T) {
+       type A []byte
+       type S struct {
+               A A
+       }
+
+       for x, in := range []S{
+               S{},
+               S{A: []byte{'1'}},
+               S{A: []byte{'1', '2', '3', '4', '5'}},
+       } {
+               data, err := Marshal(&in)
+               if err != nil {
+                       t.Errorf("#%d: got Marshal error %q, want nil", x, err)
+                       continue
+               }
+               var out S
+               err = Unmarshal(data, &out)
+               if err != nil {
+                       t.Fatalf("#%d: got Unmarshal error %q, want nil", x, err)
+               }
+               if !reflect.DeepEqual(&out, &in) {
+                       t.Fatalf("#%d: got %v, want %v", x, &out, &in)
+               }
+       }
+}
index ffe903a546b4c24b22700c4b79f5c32fe5fcd9cb..e25a9b88058a9e9e01d207eae199e2c388bf6e37 100644 (file)
@@ -44,8 +44,8 @@ import (
 // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
 // to keep some browsers from misinterpreting JSON output as HTML.
 //
-// Array and slice values encode as JSON arrays, except that
-// []byte encodes as a base64-encoded string, and a nil slice
+// Array and slice values encode as JSON arrays, except that a slice of
+// bytes encodes as a base64-encoded string, and a nil slice
 // encodes as the null JSON object.
 //
 // Struct values encode as JSON objects. Each exported struct field