diff options
author | William Poussier <william.poussier@gmail.com> | 2019-09-11 15:33:25 +0000 |
---|---|---|
committer | Daniel Martí <mvdan@mvdan.cc> | 2019-09-11 18:37:43 +0000 |
commit | cc39d8087b20fce14e60b7e5f287593da2c72749 (patch) | |
tree | dea3d59084ccb90a1f5c7d4fc581631d1c4636d1 /src/encoding/json | |
parent | 85c60bd0f3b375448dd38579acbaafdddc20b42f (diff) | |
download | go-cc39d8087b20fce14e60b7e5f287593da2c72749.tar.gz go-cc39d8087b20fce14e60b7e5f287593da2c72749.zip |
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/+/194642
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/encoding/json')
-rw-r--r-- | src/encoding/json/encode.go | 6 | ||||
-rw-r--r-- | src/encoding/json/encode_test.go | 31 |
2 files changed, 29 insertions, 8 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 0758b2fc9e..e5dd1b7799 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -481,7 +481,11 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { e.WriteString("null") return } - m := v.Interface().(encoding.TextMarshaler) + m, ok := v.Interface().(encoding.TextMarshaler) + if !ok { + e.WriteString("null") + return + } b, err := m.MarshalText() if err != nil { e.error(&MarshalerError{v.Type(), err}) diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index daab713766..18a92bae7c 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -6,6 +6,7 @@ package json import ( "bytes" + "encoding" "fmt" "log" "math" @@ -453,18 +454,31 @@ 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 +// golang.org/issue/16042. +// Even if a nil interface value is passed in, as long as +// 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 { return Marshal("0zenil0") } 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) { testCases := []struct { v interface{} @@ -478,8 +492,11 @@ func TestNilMarshal(t *testing.T) { {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}`}, + {v: struct{ M Marshaler }{(*nilJSONMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, + {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 { |