From 0ace442800fffae2e946cc4bc4fc3451085b50a8 Mon Sep 17 00:00:00 2001 From: William Poussier Date: Sat, 17 Aug 2019 21:41:48 +0200 Subject: [PATCH] encoding/json: fix panic for nil instances of TextMarshaler in map keys 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 --- src/encoding/json/encode.go | 3 +++ src/encoding/json/encode_test.go | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 67412763d64009..5c54e410f55996 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -872,6 +872,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 diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index bdf2a9f0792393..04ddb6f419d218 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -793,6 +793,20 @@ func TestTextMarshalerMapKeysAreSorted(t *testing.T) { } } +func TestIssue33675(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.