diff options
| author | William Poussier <william.poussier@gmail.com> | 2019-09-01 15:38:31 +0000 |
|---|---|---|
| committer | Daniel Martí <mvdan@mvdan.cc> | 2019-09-01 16:39:38 +0000 |
| commit | 85f3ca74882703042bcc2f17353eda192d649920 (patch) | |
| tree | dea4723907834da268ad386eec3c104a266fa336 /src/encoding | |
| parent | a806c213e7dd32520d204890fb953c8e9d1142f2 (diff) | |
| download | go-85f3ca74882703042bcc2f17353eda192d649920.tar.xz | |
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
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>
Diffstat (limited to 'src/encoding')
| -rw-r--r-- | src/encoding/json/encode.go | 3 | ||||
| -rw-r--r-- | src/encoding/json/encode_test.go | 15 |
2 files changed, 18 insertions, 0 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 07d3098f1c..f085b5a08d 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -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 diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index bdf2a9f079..642f397fb9 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -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. |
