This is an automated email from the ASF dual-hosted git repository. garydgregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-lang.git
commit 66faf46919ce196886953993697f3a1b3efd6a20 Author: Gary Gregory <[email protected]> AuthorDate: Sat Jun 20 11:29:58 2026 +0000 Reject sign characters in UnicodeUnescaper hex values (#1721). - Update changes.xml - Javadoc - Reduce vertical whitespace --- src/changes/changes.xml | 1 + .../lang3/text/translate/UnicodeUnescaper.java | 16 ++++++---------- .../lang3/text/translate/UnicodeUnescaperTest.java | 19 +++---------------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 2ee7758f7..f17854552 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -197,6 +197,7 @@ java.lang.NullPointerException: Cannot invoke <action type="fix" dev="ggregory" due-to="alhudz, Gary Gregory">Account for duplicate values in ObjectUtils.median() (#1715).</action> <action type="fix" dev="ggregory" due-to="alhudz, Gary Gregory">Fix silent int overflow in Fraction.getFraction(double) (#1717).</action> <action type="fix" dev="ggregory" due-to="alhudz, Gary Gregory">Find NaN in ArrayUtils.lastIndexOf for double and float arrays (#1718).</action> + <action type="fix" dev="ggregory" due-to="alhudz, Gary Gregory">Reject sign characters in UnicodeUnescaper hex values (#1721).</action> <!-- ADD --> <action type="add" dev="ggregory" due-to="Gary Gregory">Add JavaVersion.JAVA_27.</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_JAVA_27.</action> diff --git a/src/main/java/org/apache/commons/lang3/text/translate/UnicodeUnescaper.java b/src/main/java/org/apache/commons/lang3/text/translate/UnicodeUnescaper.java index c6a2e0939..45f6fa544 100644 --- a/src/main/java/org/apache/commons/lang3/text/translate/UnicodeUnescaper.java +++ b/src/main/java/org/apache/commons/lang3/text/translate/UnicodeUnescaper.java @@ -14,20 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.commons.lang3.text.translate; import java.io.IOException; import java.io.Writer; /** - * Translates escaped Unicode values of the form \\u+\d\d\d\d back to - * Unicode. It supports multiple 'u' characters and will work with or - * without the +. + * Translates escaped Unicode values of the form \\u+\d\d\d\d back to Unicode. It supports multiple 'u' characters and will work with or without the +. * * @since 3.0 * @deprecated As of <a href="https://commons.apache.org/proper/commons-lang/changes-report.html#a3.6">3.6</a>, use Apache Commons Text - * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/translate/UnicodeUnescaper.html"> - * UnicodeUnescaper</a>. + * <a href="https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/translate/UnicodeUnescaper.html"> + * UnicodeUnescaper</a>. */ @Deprecated public class UnicodeUnescaper extends CharSequenceTranslator { @@ -50,15 +49,12 @@ public int translate(final CharSequence input, final int index, final Writer out while (index + i < input.length() && input.charAt(index + i) == 'u') { i++; } - if (index + i < input.length() && input.charAt(index + i) == '+') { i++; } - if (index + i + 4 <= input.length()) { // Get 4 hex digits final CharSequence unicode = input.subSequence(index + i, index + i + 4); - final char firstChar = unicode.charAt(0); if (firstChar == '+' || firstChar == '-') { // Integer.parseInt accepts a leading sign, but a Unicode value is unsigned hex. @@ -72,8 +68,8 @@ public int translate(final CharSequence input, final int index, final Writer out } return i + 4; } - throw new IllegalArgumentException("Less than 4 hex digits in unicode value: '" + input.subSequence(index, input.length()) - + "' due to end of CharSequence"); + throw new IllegalArgumentException( + "Less than 4 hex digits in unicode value: '" + input.subSequence(index, input.length()) + "' due to end of CharSequence"); } return 0; } diff --git a/src/test/java/org/apache/commons/lang3/text/translate/UnicodeUnescaperTest.java b/src/test/java/org/apache/commons/lang3/text/translate/UnicodeUnescaperTest.java index 20290c5b8..2049548ac 100644 --- a/src/test/java/org/apache/commons/lang3/text/translate/UnicodeUnescaperTest.java +++ b/src/test/java/org/apache/commons/lang3/text/translate/UnicodeUnescaperTest.java @@ -32,27 +32,16 @@ class UnicodeUnescaperTest extends AbstractLangTest { @Test void testLessThanFour() { final UnicodeUnescaper uu = new UnicodeUnescaper(); - final String input = "\\0047\\u006"; - assertThrows( - IllegalArgumentException.class, - () -> uu.translate(input), - "A lack of digits in a Unicode escape sequence failed to throw an exception"); + assertThrows(IllegalArgumentException.class, () -> uu.translate(input), "A lack of digits in a Unicode escape sequence failed to throw an exception"); } @Test void testSignedValue() { final UnicodeUnescaper uu = new UnicodeUnescaper(); - // Integer.parseInt accepts a leading sign, so these used to decode to a bogus char instead of throwing. - assertThrows( - IllegalArgumentException.class, - () -> uu.translate("\\u-047"), - "A signed Unicode escape sequence failed to throw an exception"); - assertThrows( - IllegalArgumentException.class, - () -> uu.translate("\\u++0047"), - "A signed Unicode escape sequence failed to throw an exception"); + assertThrows(IllegalArgumentException.class, () -> uu.translate("\\u-047"), "A signed Unicode escape sequence failed to throw an exception"); + assertThrows(IllegalArgumentException.class, () -> uu.translate("\\u++0047"), "A signed Unicode escape sequence failed to throw an exception"); // The documented u+ notation is still accepted. assertEquals("G", uu.translate("\\u+0047"), "Failed to unescape Unicode characters with 'u+' notation"); } @@ -61,7 +50,6 @@ void testSignedValue() { @Test void testUPlus() { final UnicodeUnescaper uu = new UnicodeUnescaper(); - final String input = "\\u+0047"; assertEquals("G", uu.translate(input), "Failed to unescape Unicode characters with 'u+' notation"); } @@ -69,7 +57,6 @@ void testUPlus() { @Test void testUuuuu() { final UnicodeUnescaper uu = new UnicodeUnescaper(); - final String input = "\\uuuuuuuu0047"; final String result = uu.translate(input); assertEquals("G", result, "Failed to unescape Unicode characters with many 'u' characters");
