mirror of
https://github.com/gin-gonic/gin.git
synced 2026-09-04 22:53:34 +08:00
AsciiJSON.Render used fmt.Appendf(buf, "\\u%04x", r) for all non-ASCII runes. The %04x format is a *minimum* width, not a fixed width, so runes above U+FFFF (emoji, musical symbols, supplementary CJK, etc.) produce a 5-digit escape like \u1f600. JSON \u escapes are always exactly 4 hex digits (RFC 8259 §7), so a decoder reads the first 4 digits as a different character and treats the remaining digit(s) as literal text. The output is still syntactically valid JSON, which makes the corruption easy to miss — values silently fail to round-trip. Fix: detect runes > U+FFFF and split them into a UTF-16 surrogate pair (\uHHHH\uLLLL) before writing the escape. BMP characters continue to use the single-escape path unchanged. Add TestRenderAsciiJSONNonBMP to verify correct surrogate-pair encoding and full round-trip fidelity for 😀 (U+1F600), 𝄞 (U+1D11E), and 𠀀 (U+20000). Fixes #4688 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>