Commit 34c7765f authored by Rob Pike's avatar Rob Pike

json: treat renamed byte slices the same as []byte

Fixes #2163.

R=rsc
CC=golang-dev
https://golang.org/cl/5488068
parent 465aba66
...@@ -339,13 +339,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) { ...@@ -339,13 +339,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.WriteString("null") e.WriteString("null")
break break
} }
// Slices can be marshalled as nil, but otherwise are handled if v.Type().Elem().Kind() == reflect.Uint8 {
// as arrays. // Byte slices get special treatment; arrays don't.
fallthrough s := v.Bytes()
case reflect.Array:
if v.Type() == byteSliceType {
e.WriteByte('"') e.WriteByte('"')
s := v.Interface().([]byte)
if len(s) < 1024 { if len(s) < 1024 {
// for small buffers, using Encode directly is much faster. // for small buffers, using Encode directly is much faster.
dst := make([]byte, base64.StdEncoding.EncodedLen(len(s))) dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
...@@ -361,6 +358,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) { ...@@ -361,6 +358,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.WriteByte('"') e.WriteByte('"')
break break
} }
// Slices can be marshalled as nil, but otherwise are handled
// as arrays.
fallthrough
case reflect.Array:
e.WriteByte('[') e.WriteByte('[')
n := v.Len() n := v.Len()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
......
...@@ -82,3 +82,28 @@ func TestStringTag(t *testing.T) { ...@@ -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) 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)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment