]> Cypherpunks repositories - gostls13.git/commitdiff
json: treat renamed byte slices the same as []byte
authorRob Pike <r@golang.org>
Wed, 14 Dec 2011 19:03:28 +0000 (11:03 -0800)
committerRob Pike <r@golang.org>
Wed, 14 Dec 2011 19:03:28 +0000 (11:03 -0800)
Fixes #2163.

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

src/pkg/encoding/json/encode.go
src/pkg/encoding/json/encode_test.go

index 69deaf2a40d3ee0458abb0c70e40853b9a571521..ff8e80c091ed0876e24a99b179417ac71eea558c 100644 (file)
@@ -339,13 +339,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
                        e.WriteString("null")
                        break
                }
-               // Slices can be marshalled as nil, but otherwise are handled
-               // as arrays.
-               fallthrough
-       case reflect.Array:
-               if v.Type() == byteSliceType {
+               if v.Type().Elem().Kind() == reflect.Uint8 {
+                       // Byte slices get special treatment; arrays don't.
+                       s := v.Bytes()
                        e.WriteByte('"')
-                       s := v.Interface().([]byte)
                        if len(s) < 1024 {
                                // for small buffers, using Encode directly is much faster.
                                dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
@@ -361,6 +358,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
                        e.WriteByte('"')
                        break
                }
+               // Slices can be marshalled as nil, but otherwise are handled
+               // as arrays.
+               fallthrough
+       case reflect.Array:
                e.WriteByte('[')
                n := v.Len()
                for i := 0; i < n; i++ {
index 92f266aba63819bf87dcb26be26b436f7e9515d0..9366589f252e71b710cd5a4e2bab7cca8a2c733c 100644 (file)
@@ -82,3 +82,28 @@ func TestStringTag(t *testing.T) {
                t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
        }
 }
+
+// byte slices are special even if they're renamed types.
+type renamedByte byte
+type renamedByteSlice []byte
+type renamedRenamedByteSlice []renamedByte
+
+func TestEncodeRenamedByteSlice(t *testing.T) {
+       s := renamedByteSlice("abc")
+       result, err := Marshal(s)
+       if err != nil {
+               t.Fatal(err)
+       }
+       expect := `"YWJj"`
+       if string(result) != expect {
+               t.Errorf(" got %s want %s", result, expect)
+       }
+       r := renamedRenamedByteSlice("abc")
+       result, err = Marshal(r)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if string(result) != expect {
+               t.Errorf(" got %s want %s", result, expect)
+       }
+}