aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json/indent.go
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2023-02-20 00:42:27 -0800
committerGopher Robot <gobot@golang.org>2023-02-27 17:33:26 +0000
commit2de406bb9e26df19a31b5f6111bb221b60964d48 (patch)
tree024c7be050abfaa8ab8276b9ffac0445b927c9a9 /src/encoding/json/indent.go
parent0b5affb193ed559f2cb646e0324827f261e2e767 (diff)
downloadgo-2de406bb9e26df19a31b5f6111bb221b60964d48.tar.xz
encoding/json: use append for HTMLEscape
Use append for HTMLEscape similar to Indent and Compact. Move it to indent.go alongside Compact, as it shares similar logic. In a future CL, we will modify appendCompact to be written in terms of appendHTMLEscape, but we need to first move the JSON decoder logic out of the main loop of appendCompact. Change-Id: I131c64cd53d5d2b4ca798b37349aeefe17b418c7 Reviewed-on: https://go-review.googlesource.com/c/go/+/471198 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Joseph Tsai <joetsai@digital-static.net> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com> Auto-Submit: Joseph Tsai <joetsai@digital-static.net>
Diffstat (limited to 'src/encoding/json/indent.go')
-rw-r--r--src/encoding/json/indent.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/encoding/json/indent.go b/src/encoding/json/indent.go
index 375f71605a..99951208a0 100644
--- a/src/encoding/json/indent.go
+++ b/src/encoding/json/indent.go
@@ -11,6 +11,36 @@ func availableBuffer(b *bytes.Buffer) []byte {
return b.Bytes()[b.Len():]
}
+// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
+// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
+// so that the JSON will be safe to embed inside HTML <script> tags.
+// For historical reasons, web browsers don't honor standard HTML
+// escaping within <script> tags, so an alternative JSON encoding must be used.
+func HTMLEscape(dst *bytes.Buffer, src []byte) {
+ dst.Grow(len(src))
+ dst.Write(appendHTMLEscape(availableBuffer(dst), src))
+}
+
+func appendHTMLEscape(dst, src []byte) []byte {
+ // The characters can only appear in string literals,
+ // so just scan the string one byte at a time.
+ start := 0
+ for i, c := range src {
+ if c == '<' || c == '>' || c == '&' {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '0', '0', hex[c>>4], hex[c&0xF])
+ start = i + 1
+ }
+ // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
+ if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '2', '0', '2', hex[src[i+2]&0xF])
+ start = i + len("\u2029")
+ }
+ }
+ return append(dst, src[start:]...)
+}
+
// Compact appends to dst the JSON-encoded src with
// insignificant space characters elided.
func Compact(dst *bytes.Buffer, src []byte) error {