Commit cdc0ebbe authored by Håvard Haugen's avatar Håvard Haugen Committed by Brad Fitzpatrick

encoding/json: respect json.Marshaler when encoding byte kind slices

Fixes #13783.

Change-Id: I0122c1f0cf4075acabf5f58241bded1835699dc1
Reviewed-on: https://go-review.googlesource.com/19725Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 2cefd12a
...@@ -679,7 +679,9 @@ func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) { ...@@ -679,7 +679,9 @@ func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
func newSliceEncoder(t reflect.Type) encoderFunc { func newSliceEncoder(t reflect.Type) encoderFunc {
// Byte slices get special treatment; arrays don't. // Byte slices get special treatment; arrays don't.
if t.Elem().Kind() == reflect.Uint8 { if t.Elem().Kind() == reflect.Uint8 &&
!t.Elem().Implements(marshalerType) &&
!t.Elem().Implements(textMarshalerType) {
return encodeByteSlice return encodeByteSlice
} }
enc := &sliceEncoder{newArrayEncoder(t)} enc := &sliceEncoder{newArrayEncoder(t)}
......
...@@ -6,6 +6,7 @@ package json ...@@ -6,6 +6,7 @@ package json
import ( import (
"bytes" "bytes"
"fmt"
"math" "math"
"reflect" "reflect"
"testing" "testing"
...@@ -537,6 +538,60 @@ func TestEncodeString(t *testing.T) { ...@@ -537,6 +538,60 @@ func TestEncodeString(t *testing.T) {
} }
} }
type jsonbyte byte
func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) }
type textbyte byte
func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) }
type jsonint int
func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) }
type textint int
func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) }
func tenc(format string, a ...interface{}) ([]byte, error) {
var buf bytes.Buffer
fmt.Fprintf(&buf, format, a...)
return buf.Bytes(), nil
}
// Issue 13783
func TestEncodeBytekind(t *testing.T) {
testdata := []struct {
data interface{}
want string
}{
{byte(7), "7"},
{jsonbyte(7), `{"JB":7}`},
{textbyte(4), `"TB:4"`},
{jsonint(5), `{"JI":5}`},
{textint(1), `"TI:1"`},
{[]byte{0, 1}, `"AAE="`},
{[]jsonbyte{0, 1}, `[{"JB":0},{"JB":1}]`},
{[][]jsonbyte{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`},
{[]textbyte{2, 3}, `["TB:2","TB:3"]`},
{[]jsonint{5, 4}, `[{"JI":5},{"JI":4}]`},
{[]textint{9, 3}, `["TI:9","TI:3"]`},
{[]int{9, 3}, `[9,3]`},
}
for _, d := range testdata {
js, err := Marshal(d.data)
if err != nil {
t.Error(err)
continue
}
got, want := string(js), d.want
if got != want {
t.Errorf("got %s, want %s", got, want)
}
}
}
func TestTextMarshalerMapKeysAreSorted(t *testing.T) { func TestTextMarshalerMapKeysAreSorted(t *testing.T) {
b, err := Marshal(map[unmarshalerText]int{ b, err := Marshal(map[unmarshalerText]int{
{"x", "y"}: 1, {"x", "y"}: 1,
......
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