mirror of https://github.com/golang/go.git
encoding/json: encode nil Marshaler as "null"
Fixes #16042. Change-Id: I0a28aa004246b7b0ffaaab457e077ad9035363c2 Reviewed-on: https://go-review.googlesource.com/31932 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
c439a5d8b7
commit
add721ef91
|
|
@ -443,7 +443,11 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
|
|||
e.WriteString("null")
|
||||
return
|
||||
}
|
||||
m := v.Interface().(Marshaler)
|
||||
m, ok := v.Interface().(Marshaler)
|
||||
if !ok {
|
||||
e.WriteString("null")
|
||||
return
|
||||
}
|
||||
b, err := m.MarshalJSON()
|
||||
if err == nil {
|
||||
// copy JSON into buffer, checking validity.
|
||||
|
|
|
|||
|
|
@ -293,6 +293,44 @@ type BugX struct {
|
|||
BugB
|
||||
}
|
||||
|
||||
// Issue 16042. Even if a nil interface value is passed in
|
||||
// as long as it implements MarshalJSON, it should be marshaled.
|
||||
type nilMarshaler string
|
||||
|
||||
func (nm *nilMarshaler) MarshalJSON() ([]byte, error) {
|
||||
if nm == nil {
|
||||
return Marshal("0zenil0")
|
||||
}
|
||||
return Marshal("zenil:" + string(*nm))
|
||||
}
|
||||
|
||||
// Issue 16042.
|
||||
func TestNilMarshal(t *testing.T) {
|
||||
testCases := []struct {
|
||||
v interface{}
|
||||
want string
|
||||
}{
|
||||
{v: nil, want: `null`},
|
||||
{v: new(float64), want: `0`},
|
||||
{v: []interface{}(nil), want: `null`},
|
||||
{v: []string(nil), want: `null`},
|
||||
{v: map[string]string(nil), want: `null`},
|
||||
{v: []byte(nil), want: `null`},
|
||||
{v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`},
|
||||
{v: struct{ M Marshaler }{}, want: `{"M":null}`},
|
||||
{v: struct{ M Marshaler }{(*nilMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
|
||||
{v: struct{ M interface{} }{(*nilMarshaler)(nil)}, want: `{"M":null}`},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
out, err := Marshal(tt.v)
|
||||
if err != nil || string(out) != tt.want {
|
||||
t.Errorf("Marshal(%#v) = %#q, %#v, want %#q, nil", tt.v, out, err, tt.want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 5245.
|
||||
func TestEmbeddedBug(t *testing.T) {
|
||||
v := BugB{
|
||||
|
|
|
|||
Loading…
Reference in New Issue