]> Cypherpunks.ru repositories - gostls13.git/commitdiff
encoding/json: encode \b and \f as '\b' and '\f' in JSON strings
authorJoe Tsai <joetsai@digital-static.net>
Mon, 21 Aug 2023 20:06:23 +0000 (13:06 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 23 Aug 2023 21:37:55 +0000 (21:37 +0000)
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 <joetsai@digital-static.net>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/encoding/json/encode.go
src/encoding/json/encode_test.go

index 38b98a57f7c7fe6950051dd7365f2a3b93950963..9ba717c9ceb20dbc7217320b912cafccc7a1d188 100644 (file)
@@ -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':
index d027972d8a0a777258935f835f7d25d3a6179f66..79723488012fe0bc763f0a568af747eed5585d63 100644 (file)
@@ -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"`},