summaryrefslogtreecommitdiff
path: root/misc.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc.go')
-rw-r--r--misc.go47
1 files changed, 42 insertions, 5 deletions
diff --git a/misc.go b/misc.go
index 4f8e55e..92757f4 100644
--- a/misc.go
+++ b/misc.go
@@ -44,25 +44,43 @@ func writeRune(w io.Writer, c rune) (int, error) {
// JSON string encoding ////////////////////////////////////////////////////////
+// BackSlashEscapeMode identifies one of the three ways that a
+// character may be represented in a JSON string:
+//
+// - literally (no backslash escaping)
+//
+// - as a short "well-known" `\X` backslash sequence (where `X` is a
+// single-character)
+//
+// - as a long Unicode `\uXXXX` backslash sequence
type BackslashEscapeMode uint8
const (
- BackslashEscapeNone = BackslashEscapeMode(iota)
+ BackslashEscapeNone BackslashEscapeMode = iota
BackslashEscapeShort
BackslashEscapeUnicode
)
+// A BackslashEscaper controls how a ReEncoder emits a character in a
+// JSON string. The `rune` argument is the character being
+// considered, and the `BackslashEscapeMode` argument is how it was
+// originally encoded in the input.
type BackslashEscaper = func(rune, BackslashEscapeMode) BackslashEscapeMode
+// EscapePreserve is a BackslashEscaper that preserves the original
+// input escaping.
func EscapePreserve(_ rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
return wasEscaped
}
+// EscapeJSSafe is a BackslashEscaper that escapes strings such that
+// the JSON safe to embed in JS; it otherwise preserves the original
+// input escaping.
+//
+// JSON is notionally a JS subset, but that's not actually true; so
+// more conservative backslash-escaping is necessary to safely embed
+// it in JS. http://timelessrepo.com/json-isnt-a-javascript-subset
func EscapeJSSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
- // JSON is notionally a JS subset, but that's not actually
- // true.
- //
- // http://timelessrepo.com/json-isnt-a-javascript-subset
switch c {
case '\u2028', '\u2029':
return BackslashEscapeUnicode
@@ -71,6 +89,9 @@ func EscapeJSSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
}
}
+// EscapeHTMLSafe is a BackslashEscaper that escapes strings such that
+// the JSON is safe to embed in HTML; it otherwise preserves the
+// original input escaping.
func EscapeHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
switch c {
case '&', '<', '>':
@@ -80,6 +101,15 @@ func EscapeHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
}
}
+// EscapeDefault is a BackslashEscaper that mimics the default
+// behavior of encoding/json.
+//
+// It is like EscapeHTMLSafe, but also uses long Unicode `\uXXXX`
+// sequences for `\b`, `\f`, and the `\uFFFD` Unicode replacement
+// character.
+//
+// A ReEncoder uses EscapeDefault if a BackslashEscaper is not
+// specified.
func EscapeDefault(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
switch c {
case '\b', '\f', utf8.RuneError:
@@ -89,6 +119,13 @@ func EscapeDefault(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
}
}
+// EscapeDefault is a BackslashEscaper that mimics the default
+// behavior of an encoding/json.Encoder that has had
+// SetEscapeHTML(false) called on it.
+//
+// It is like EscapeJSSafe, but also uses long Unicode `\uXXXX`
+// sequences for `\b`, `\f`, and the `\uFFFD` Unicode replacement
+// character.
func EscapeDefaultNonHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode {
switch c {
case '\b', '\f', utf8.RuneError: