diff --git a/src/encoding/json/bench_test.go b/src/encoding/json/bench_test.go index f2592e3dbdf55f..f92d39f0c657aa 100644 --- a/src/encoding/json/bench_test.go +++ b/src/encoding/json/bench_test.go @@ -297,6 +297,22 @@ func BenchmarkIssue10335(b *testing.B) { }) } +func BenchmarkIssue34127(b *testing.B) { + b.ReportAllocs() + j := struct { + Bar string `json:"bar,string"` + }{ + Bar: `foobar`, + } + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + if _, err := Marshal(&j); err != nil { + b.Fatal(err) + } + } + }) +} + func BenchmarkUnmapped(b *testing.B) { b.ReportAllocs() j := []byte(`{"s": "hello", "y": 2, "o": {"x": 0}, "a": [1, 99, {"x": 1}]}`) diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index f085b5a08d76db..d6821c113556b7 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -601,11 +601,11 @@ func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { return } if opts.quoted { - sb, err := Marshal(v.String()) - if err != nil { - e.error(err) - } - e.string(string(sb), opts.escapeHTML) + b := make([]byte, 0, v.Len()+2) + b = append(b, '"') + b = append(b, []byte(v.String())...) + b = append(b, '"') + e.stringBytes(b, opts.escapeHTML) } else { e.string(v.String(), opts.escapeHTML) } diff --git a/src/encoding/json/stream_test.go b/src/encoding/json/stream_test.go index e3317ddeb0b5d3..22befc105cdfb2 100644 --- a/src/encoding/json/stream_test.go +++ b/src/encoding/json/stream_test.go @@ -158,6 +158,27 @@ func TestEncoderSetEscapeHTML(t *testing.T) { } } +// https://golang.org/issue/34154 +func TestEncoderStringOptionSetEscapeHTMLFalse(t *testing.T) { + value := struct { + Bar string `json:"bar,string"` + }{ + Bar: `foobar`, + } + want := `{"bar":"\"foobar\""}` + + var buf bytes.Buffer + enc := NewEncoder(&buf) + enc.SetEscapeHTML(false) + if err := enc.Encode(value); err != nil { + t.Fatalf("Encode: %s", err) + } + if got := strings.TrimSpace(buf.String()); got != want { + t.Errorf("SetEscapeHTML(false) Encode = %#q, want %#q", + got, want) + } +} + func TestDecoder(t *testing.T) { for i := 0; i <= len(streamTest); i++ { // Use stream without newlines as input,