From a7526bbf72dfe0fde00d88f85fd6cddccdb3a345 Mon Sep 17 00:00:00 2001 From: Meng Zhuo Date: Thu, 21 Jan 2021 22:53:30 +0800 Subject: encoding/json: marshal maps using reflect.Value.MapRange MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Map serialization using reflect.Value.MapIndex cannot retrieve map keys that contain a NaN, resulting in a panic. Switch the implementation to use the reflect.Value.MapRange method instead, which iterates over all map entries regardless of whether they are directly retrievable. Note that according to RFC 8259, section 4, a JSON object should have unique names, but does not forbid the occurrence of duplicate names. Fixes #43207 Change-Id: If4bc55229b1f64b8ca4b0fed37549725efdace39 Reviewed-on: https://go-review.googlesource.com/c/go/+/278632 Trust: Meng Zhuo Trust: Joe Tsai Trust: Bryan C. Mills Run-TryBot: Meng Zhuo TryBot-Result: Go Bot Reviewed-by: Joe Tsai Reviewed-by: Daniel Martí --- src/encoding/json/encode_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/encoding/json/encode_test.go') diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index 42bb09d5cd..0dad951095 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -245,6 +245,22 @@ func TestUnsupportedValues(t *testing.T) { } } +// Issue 43207 +func TestMarshalTextFloatMap(t *testing.T) { + m := map[textfloat]string{ + textfloat(math.NaN()): "1", + textfloat(math.NaN()): "1", + } + got, err := Marshal(m) + if err != nil { + t.Errorf("Marshal() error: %v", err) + } + want := `{"TF:NaN":"1","TF:NaN":"1"}` + if string(got) != want { + t.Errorf("Marshal() = %s, want %s", got, want) + } +} + // Ref has Marshaler and Unmarshaler methods with pointer receiver. type Ref int @@ -854,6 +870,10 @@ func tenc(format string, a ...interface{}) ([]byte, error) { return buf.Bytes(), nil } +type textfloat float64 + +func (f textfloat) MarshalText() ([]byte, error) { return tenc(`TF:%0.2f`, f) } + // Issue 13783 func TestEncodeBytekind(t *testing.T) { testdata := []struct { @@ -872,6 +892,7 @@ func TestEncodeBytekind(t *testing.T) { {[]jsonint{5, 4}, `[{"JI":5},{"JI":4}]`}, {[]textint{9, 3}, `["TI:9","TI:3"]`}, {[]int{9, 3}, `[9,3]`}, + {[]textfloat{12, 3}, `["TF:12.00","TF:3.00"]`}, } for _, d := range testdata { js, err := Marshal(d.data) -- cgit v1.3