Commit cc39d808 authored by William Poussier's avatar William Poussier Committed by Daniel Martí

encoding/json: encode nil encoding.TextMarshaler instance as "null"

Fixes #34235.

Change-Id: Ia3795fd18860530fa6a4b171545f525e784ffdcb
GitHub-Last-Rev: 1a319c452857818f7aaf22ef46823b43ca9b2276
GitHub-Pull-Request: golang/go#34238
Reviewed-on: https://go-review.googlesource.com/c/go/+/194642Reviewed-by: default avatarDaniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 85c60bd0
...@@ -481,7 +481,11 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { ...@@ -481,7 +481,11 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
e.WriteString("null") e.WriteString("null")
return return
} }
m := v.Interface().(encoding.TextMarshaler) m, ok := v.Interface().(encoding.TextMarshaler)
if !ok {
e.WriteString("null")
return
}
b, err := m.MarshalText() b, err := m.MarshalText()
if err != nil { if err != nil {
e.error(&MarshalerError{v.Type(), err}) e.error(&MarshalerError{v.Type(), err})
......
...@@ -6,6 +6,7 @@ package json ...@@ -6,6 +6,7 @@ package json
import ( import (
"bytes" "bytes"
"encoding"
"fmt" "fmt"
"log" "log"
"math" "math"
...@@ -453,18 +454,31 @@ type BugX struct { ...@@ -453,18 +454,31 @@ type BugX struct {
BugB BugB
} }
// Issue 16042. Even if a nil interface value is passed in // golang.org/issue/16042.
// as long as it implements MarshalJSON, it should be marshaled. // Even if a nil interface value is passed in, as long as
type nilMarshaler string // it implements Marshaler, it should be marshaled.
type nilJSONMarshaler string
func (nm *nilMarshaler) MarshalJSON() ([]byte, error) { func (nm *nilJSONMarshaler) MarshalJSON() ([]byte, error) {
if nm == nil { if nm == nil {
return Marshal("0zenil0") return Marshal("0zenil0")
} }
return Marshal("zenil:" + string(*nm)) return Marshal("zenil:" + string(*nm))
} }
// Issue 16042. // golang.org/issue/34235.
// Even if a nil interface value is passed in, as long as
// it implements encoding.TextMarshaler, it should be marshaled.
type nilTextMarshaler string
func (nm *nilTextMarshaler) MarshalText() ([]byte, error) {
if nm == nil {
return []byte("0zenil0"), nil
}
return []byte("zenil:" + string(*nm)), nil
}
// See golang.org/issue/16042 and golang.org/issue/34235.
func TestNilMarshal(t *testing.T) { func TestNilMarshal(t *testing.T) {
testCases := []struct { testCases := []struct {
v interface{} v interface{}
...@@ -478,8 +492,11 @@ func TestNilMarshal(t *testing.T) { ...@@ -478,8 +492,11 @@ func TestNilMarshal(t *testing.T) {
{v: []byte(nil), want: `null`}, {v: []byte(nil), want: `null`},
{v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`}, {v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`},
{v: struct{ M Marshaler }{}, want: `{"M":null}`}, {v: struct{ M Marshaler }{}, want: `{"M":null}`},
{v: struct{ M Marshaler }{(*nilMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, {v: struct{ M Marshaler }{(*nilJSONMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
{v: struct{ M interface{} }{(*nilMarshaler)(nil)}, want: `{"M":null}`}, {v: struct{ M interface{} }{(*nilJSONMarshaler)(nil)}, want: `{"M":null}`},
{v: struct{ M encoding.TextMarshaler }{}, want: `{"M":null}`},
{v: struct{ M encoding.TextMarshaler }{(*nilTextMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
{v: struct{ M interface{} }{(*nilTextMarshaler)(nil)}, want: `{"M":null}`},
} }
for _, tt := range testCases { for _, tt := range testCases {
......
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