fix: encode supplementary Unicode as surrogate pairs in AsciiJSON

Characters above U+FFFF (emoji, math symbols, etc.) were escaped as
\u1f600 (5+ hex digits) which is invalid JSON per RFC 8259. Strict
JSON parsers reject this output.

Per the spec, supplementary plane characters must be encoded as
UTF-16 surrogate pairs (e.g. U+1F600 becomes \uD83D\uDE00).
This commit is contained in:
barry3406 2026-04-09 06:10:36 -07:00
parent e7c8e50895
commit cf3be80b0e

View File

@ -160,11 +160,19 @@ func (r AsciiJSON) Render(w http.ResponseWriter) error {
}
var buffer bytes.Buffer
escapeBuf := make([]byte, 0, 6) // Preallocate 6 bytes for Unicode escape sequences
escapeBuf := make([]byte, 0, 12) // Preallocate for surrogate pair escape sequences
for _, r := range bytesconv.BytesToString(ret) {
if r > unicode.MaxASCII {
escapeBuf = fmt.Appendf(escapeBuf[:0], "\\u%04x", r) // Reuse escapeBuf
if r > 0xFFFF {
// Supplementary plane: encode as UTF-16 surrogate pair per RFC 8259
r -= 0x10000
high := 0xD800 + (r>>10)&0x3FF
low := 0xDC00 + r&0x3FF
escapeBuf = fmt.Appendf(escapeBuf[:0], "\\u%04x\\u%04x", high, low)
} else {
escapeBuf = fmt.Appendf(escapeBuf[:0], "\\u%04x", r)
}
buffer.Write(escapeBuf)
} else {
buffer.WriteByte(byte(r))