From 2763146099384e320e2d1c0fc41b3b3906050652 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Mon, 21 Aug 2023 13:06:23 -0700 Subject: [PATCH] encoding/json: encode \b and \f as '\b' and '\f' in JSON strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to RFC 8259, there are exactly 5 control characters that have a shorter escape sequence than the generic \uXXXX format. Over the years, we added ad-hoc support for the short sequences: * https://go.dev/cl/4678046 supports \r and \n * https://go.dev/cl/162340043 supports \t This CL completes the set by supporting \b and \f. This may change the encoding of strings in relatively rare cases, but is a permissible change since the Go 1 compatibility document does not guarantee that "json" produces byte-for-byte identical outputs. In fact, we have made even more observable output changes in the past such as with https://go.dev/cl/30371 which changes the representation of many JSON numbers. This change is to prepare the path forward for a potential v2 "json" package, which has more consistent encoding of JSON strings. Change-Id: I11102a0602dfb1a0c14eaad82ed23e8df7553c6b Reviewed-on: https://go-review.googlesource.com/c/go/+/521675 Auto-Submit: Joseph Tsai Reviewed-by: Ian Lance Taylor Reviewed-by: Daniel Martí TryBot-Result: Gopher Robot Run-TryBot: Joseph Tsai Reviewed-by: Bryan Mills --- src/encoding/json/encode.go | 4 ++++ src/encoding/json/encode_test.go | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 38b98a57f7..9ba717c9ce 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -969,6 +969,10 @@ func appendString[Bytes []byte | string](dst []byte, src Bytes, escapeHTML bool) switch b { case '\\', '"': dst = append(dst, '\\', b) + case '\b': + dst = append(dst, '\\', 'b') + case '\f': + dst = append(dst, '\\', 'f') case '\n': dst = append(dst, '\\', 'n') case '\r': diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index d027972d8a..7972348801 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -113,7 +113,7 @@ func TestRoundtripStringTag(t *testing.T) { "BoolStr": "false", "IntStr": "0", "UintptrStr": "0", - "StrStr": "\"\\u0008\\u000c\\n\\r\\t\\\"\\\\\"", + "StrStr": "\"\\b\\f\\n\\r\\t\\\"\\\\\"", "NumberStr": "0" }`, }, @@ -795,11 +795,11 @@ var encodeStringTests = []struct { {"\x05", `"\u0005"`}, {"\x06", `"\u0006"`}, {"\x07", `"\u0007"`}, - {"\x08", `"\u0008"`}, + {"\x08", `"\b"`}, {"\x09", `"\t"`}, {"\x0a", `"\n"`}, {"\x0b", `"\u000b"`}, - {"\x0c", `"\u000c"`}, + {"\x0c", `"\f"`}, {"\x0d", `"\r"`}, {"\x0e", `"\u000e"`}, {"\x0f", `"\u000f"`},