]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: fix panic for nil instances of TextMarshaler in map keys
authorWilliam Poussier <william.poussier@gmail.com>
Sun, 1 Sep 2019 15:38:31 +0000 (15:38 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Sun, 1 Sep 2019 16:39:38 +0000 (16:39 +0000)
This change adds a a check in the encodeWithString.resolve method
to ensure that a reflect.Value with kind Ptr is not nil before
the type assertion to TextMarshaler.

If the value is nil, the method returns a nil error, and the map key
encodes to an empty string.

Fixes #33675

Change-Id: I0a04cf690ae67006f6a9c5f8cbb4cc99d236bca8
GitHub-Last-Rev: 6c987c90846f854e21814dbfb3a073605ec8a94c
GitHub-Pull-Request: golang/go#33700
Reviewed-on: https://go-review.googlesource.com/c/go/+/190697
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
src/encoding/json/encode.go
src/encoding/json/encode_test.go

index 07d3098f1c1edf4fa1746752177cfec3a1551366..f085b5a08d76dbae7e29457e4d9cd1d4d61e7286 100644 (file)
@@ -932,6 +932,9 @@ func (w *reflectWithString) resolve() error {
                return nil
        }
        if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
+               if w.v.Kind() == reflect.Ptr && w.v.IsNil() {
+                       return nil
+               }
                buf, err := tm.MarshalText()
                w.s = string(buf)
                return err
index bdf2a9f07923939f5258d6275e7843cd95960348..642f397fb95a7b9457178ff9a7dfa62d046ebe0b 100644 (file)
@@ -793,6 +793,21 @@ func TestTextMarshalerMapKeysAreSorted(t *testing.T) {
        }
 }
 
+// https://golang.org/issue/33675
+func TestNilMarshalerTextMapKey(t *testing.T) {
+       b, err := Marshal(map[*unmarshalerText]int{
+               (*unmarshalerText)(nil):    1,
+               &unmarshalerText{"A", "B"}: 2,
+       })
+       if err != nil {
+               t.Fatalf("Failed to Marshal *text.Marshaler: %v", err)
+       }
+       const want = `{"":1,"A:B":2}`
+       if string(b) != want {
+               t.Errorf("Marshal map with *text.Marshaler keys: got %#q, want %#q", b, want)
+       }
+}
+
 var re = regexp.MustCompile
 
 // syntactic checks on form of marshaled floating point numbers.