]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: encode nil encoding.TextMarshaler instance as "null"
authorWilliam Poussier <william.poussier@gmail.com>
Wed, 11 Sep 2019 15:33:25 +0000 (15:33 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Wed, 11 Sep 2019 18:37:43 +0000 (18:37 +0000)
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>

src/encoding/json/encode.go
src/encoding/json/encode_test.go

index 0758b2fc9e82b685480a3c60df027ce3de4b816b..e5dd1b7799b484d6b8a5cfd0a57e6567df25f144 100644 (file)
@@ -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})
index daab713766c550fe902ab148fdee046f8d7a77cd..18a92bae7c76e6d1b69157574f120eb41c2cae74 100644 (file)
@@ -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 {