summaryrefslogtreecommitdiff
path: root/encode_escape.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-16 19:06:46 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-18 22:45:54 -0700
commit00187950437a10952b82353405e5ba4b4515fb29 (patch)
tree826c4ff76310bf6f58e79f37f2107c329810aaa8 /encode_escape.go
parenta87d6cbbb51a19071c5c742ef3c91bbb90a727c6 (diff)
reencode: Don't normalize the capitalization of \uXXXX hex escapes
Diffstat (limited to 'encode_escape.go')
-rw-r--r--encode_escape.go39
1 files changed, 36 insertions, 3 deletions
diff --git a/encode_escape.go b/encode_escape.go
index c9e2bc9..664c762 100644
--- a/encode_escape.go
+++ b/encode_escape.go
@@ -36,7 +36,8 @@ const (
// - as a short "well-known" `\X` backslash sequence (where `X` is a
// single-character)
//
-// - as a long Unicode `\uXXXX` backslash sequence
+// - as a long Unicode `\uXXXX` backslash sequence (with 16
+// permutations of capitalization)
//
// - as a raw byte; this allows you to emit invalid JSON; JSON must
// be valid UTF-8, but this allows you to emit arbitrary binary
@@ -47,8 +48,29 @@ type BackslashEscapeMode = jsonstring.BackslashEscapeMode
const (
BackslashEscapeNone = jsonstring.BackslashEscapeNone
BackslashEscapeShort = jsonstring.BackslashEscapeShort
- BackslashEscapeUnicode = jsonstring.BackslashEscapeUnicode
BackslashEscapeRawByte = jsonstring.BackslashEscapeRawByte
+
+ BackslashEscapeUnicodeXXXX = jsonstring.BackslashEscapeUnicodeXXXX
+ BackslashEscapeUnicodeXXXx = jsonstring.BackslashEscapeUnicodeXXXx
+ BackslashEscapeUnicodeXXxX = jsonstring.BackslashEscapeUnicodeXXxX
+ BackslashEscapeUnicodeXXxx = jsonstring.BackslashEscapeUnicodeXXxx
+ BackslashEscapeUnicodeXxXX = jsonstring.BackslashEscapeUnicodeXxXX
+ BackslashEscapeUnicodeXxXx = jsonstring.BackslashEscapeUnicodeXxXx
+ BackslashEscapeUnicodeXxxX = jsonstring.BackslashEscapeUnicodeXxxX
+ BackslashEscapeUnicodeXxxx = jsonstring.BackslashEscapeUnicodeXxxx
+ BackslashEscapeUnicodexXXX = jsonstring.BackslashEscapeUnicodexXXX
+ BackslashEscapeUnicodexXXx = jsonstring.BackslashEscapeUnicodexXXx
+ BackslashEscapeUnicodexXxX = jsonstring.BackslashEscapeUnicodexXxX
+ BackslashEscapeUnicodexXxx = jsonstring.BackslashEscapeUnicodexXxx
+ BackslashEscapeUnicodexxXX = jsonstring.BackslashEscapeUnicodexxXX
+ BackslashEscapeUnicodexxXx = jsonstring.BackslashEscapeUnicodexxXx
+ BackslashEscapeUnicodexxxX = jsonstring.BackslashEscapeUnicodexxxX
+ BackslashEscapeUnicodexxxx = jsonstring.BackslashEscapeUnicodexxxx
+
+ BackslashEscapeUnicodeMin = jsonstring.BackslashEscapeUnicodeMin
+ BackslashEscapeUnicodeMax = jsonstring.BackslashEscapeUnicodeMax
+
+ BackslashEscapeUnicode = jsonstring.BackslashEscapeUnicode // back-compat
)
func hexToInt(c byte) rune {
@@ -72,13 +94,24 @@ func hexToRune(a, b, c, d byte) rune {
hexToInt(d)<<0
}
+func hexToMode(a, b, c, d byte) BackslashEscapeMode {
+ // The 0b0010_0000 bit is the ASCII "lowercase bit".
+ return BackslashEscapeUnicodeMin + BackslashEscapeMode(0|
+ ((a&0b0010_0000)>>2)|
+ ((b&0b0010_0000)>>3)|
+ ((c&0b0010_0000)>>4)|
+ ((d&0b0010_0000)>>5))
+}
+
// 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.
//
// The ReEncoder will panic if a BackslashEscaper returns an unknown
-// BackslashEscapeMode.
+// BackslashEscapeMode. However, a BackslashEscaper should be
+// permissive of BackslashEscapeModes it doesn't recognize; it is safe
+// to just return them unmodified.
type BackslashEscaper = func(rune, BackslashEscapeMode) BackslashEscapeMode
// EscapePreserve is a BackslashEscaper that preserves the original