aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json/indent.go
diff options
context:
space:
mode:
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 {