src/encoding/json/decode.go | 5 +++++ src/encoding/json/decode_test.go | 33 +++++++++++++++++++++++++++++++-- diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index b43484692e18565d453fa7c8b364435bf7e56803..b60e2bb0b2c4dbee63f3a4d7e59c7cb03550abe3 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -1217,6 +1217,11 @@ r := d.safeUnquote if r == -1 { return s, true } + // Only perform up to one safe unquote for each re-scanned string + // literal. In some edge cases, the decoder unquotes a literal a second + // time, even after another literal has been re-scanned. Thus, only the + // first unquote can safely use safeUnquote. + d.safeUnquote = 0 b := make([]byte, len(s)+2*utf8.UTFMax) w := copy(b, s[0:r]) diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go index 498bd97b46ef41dc9a2ceba27d449be428fc6d30..a49181e9823d378e1eac372281722981678e3ad7 100644 --- a/src/encoding/json/decode_test.go +++ b/src/encoding/json/decode_test.go @@ -2419,7 +2419,7 @@ *m = textUnmarshalerString(strings.ToLower(string(text))) return nil } -// Test unmarshal to a map, with map key is a user defined type. +// Test unmarshal to a map, where the map key is a user defined type. // See golang.org/issues/34437. func TestUnmarshalMapWithTextUnmarshalerStringKey(t *testing.T) { var p map[textUnmarshalerString]string @@ -2428,6 +2428,35 @@ t.Fatalf("Unmarshal unexpected error: %v", err) } if _, ok := p["foo"]; !ok { - t.Errorf(`Key "foo" is not existed in map: %v`, p) + t.Errorf(`Key "foo" does not exist in map: %v`, p) + } +} + +func TestUnmarshalRescanLiteralMangledUnquote(t *testing.T) { + // See golang.org/issues/38105. + var p map[textUnmarshalerString]string + if err := Unmarshal([]byte(`{"开源":"12345开源"}`), &p); err != nil { + t.Fatalf("Unmarshal unexpected error: %v", err) + } + if _, ok := p["开源"]; !ok { + t.Errorf(`Key "开源" does not exist in map: %v`, p) + } + + // See golang.org/issues/38126. + type T struct { + F1 string `json:"F1,string"` + } + t1 := T{"aaa\tbbb"} + + b, err := Marshal(t1) + if err != nil { + t.Fatalf("Marshal unexpected error: %v", err) + } + var t2 T + if err := Unmarshal(b, &t2); err != nil { + t.Fatalf("Unmarshal unexpected error: %v", err) + } + if t1 != t2 { + t.Errorf("Marshal and Unmarshal roundtrip mismatch: want %q got %q", t1, t2) } }