Repository navigation
Pad BMP code points to four hex digits in UnicodeEscaper.toUtf16Escape - #1858
Merged
garydgregory merged 1 commit intoNov 3, 2026
Merged
Conversation
The BMP branch of the protected toUtf16Escape hook returned "\\u" + Integer.toHexString, so code points below U+1000 produced short escapes such as \u41 that no \u reader decodes, while translate() pads the same code point through HEX_DIGITS. JavaUnicodeEscaper overrode the hook with the surrogate-pair form only and threw ArrayIndexOutOfBoundsException for every BMP code point. Left-pad the BMP hex to four digits and drop the JavaUnicodeEscaper override, which is redundant since the base method emits the surrogate-pair form itself. translate() output is unchanged.
Member
|
@alhudz thanks, merged 🚀 |
garydgregory
added a commit
that referenced
this pull request
Nov 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
UnicodeEscaper.toUtf16Escape(int)is the protected hook documented since 3.2 as returning the\uXXXXform. Its BMP branch is"\\u" + hex(codePoint), andhex()isInteger.toHexString, so any code point below U+1000 comes back short:No
\ureader decodes those (UnicodeUnescaperpasses\u41through unchanged), whiletranslate()writes the same code point padded throughHEX_DIGITS, so the hook and the translator disagree on BMP input.JavaUnicodeEscaperoverrides the hook with the surrogate-pair form only and indexessurrogatePair[1]unconditionally, sonew JavaUnicodeEscaper(0, Integer.MAX_VALUE, true).toUtf16Escape('A')throwsArrayIndexOutOfBoundsException.The fix left-pads the BMP hex to four digits inside
toUtf16Escape, next to the surrogate-pair branch from #1726, and drops theJavaUnicodeEscaperoverride, which that PR made redundant: the base method now emits the same surrogate-pair form, so subclasses and direct callers get a well-formed escape for every code point. Output oftranslate(), and therefore ofStringEscapeUtils.escapeJava,escapeEcmaScriptandescapeJson, is byte for byte unchanged;translate()only reaches the hook for supplementary code points, where both forms were already identical.UnicodeEscaperTest.testToUtf16EscapeBmpandJavaUnicodeEscaperTest.testToUtf16EscapeBmpfail before the change (\u0and theArrayIndexOutOfBoundsException) and pass after.Following up on the question on #1726: the Commons Text
UnicodeEscaper.toUtf16Escapestill has the pre-#1726 body ("\\u" + hex(codePoint)for every code point), so it has both the supplementary-code-point defect and this padding one;JavaUnicodeEscaperthere has the same BMPArrayIndexOutOfBoundsException. I will raise the same change on Commons Text separately.Before you push a pull request, review this list:
mvn; that'smvnon the command line by itself.