mirror of
https://github.com/gin-gonic/gin.git
synced 2026-09-07 08:52:04 +08:00
AsciiJSON escaped every non-ASCII rune with fmt.Appendf(buf, "\u%04x", r), but %04x is a minimum width, not a fixed width. Runes outside the Basic Multilingual Plane (e.g. emoji) need 5+ hex digits, so a single malformed \uXXXXX token was written instead of a valid 4-digit JSON \u escape. The output stayed syntactically valid JSON, so this was easy to miss, but a decoder reads the first 4 hex digits as one character and treats the rest as literal text, corrupting the value silently. RFC 8259 §7 requires code points outside the BMP to be encoded as a UTF-16 surrogate pair. Use unicode/utf16.EncodeRune to produce the pair for those runes while keeping the existing single-escape path for BMP characters. Fixes #4688