Skip to content

Commit a47c2c0

Browse files
committed
reject hex letters in NumericEntityUnescaper decimal scan
1 parent b509e0b commit a47c2c0

2 files changed

Lines changed: 13 additions & 2 deletions

File tree

src/main/java/org/apache/commons/lang3/text/translate/NumericEntityUnescaper.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,10 @@ public int translate(final CharSequence input, final int index, final Writer out
120120
}
121121
}
122122
int end = start;
123-
// Note that this supports character codes without a ; on the end
124-
while (end < seqEnd && CharUtils.isHex(input.charAt(end))) {
123+
// Note that this supports character codes without a ; on the end.
124+
// A decimal entity (&#...) only holds decimal digits; a-f are hex digits and must
125+
// not be consumed here, otherwise the following text is swallowed into a failed parse.
126+
while (end < seqEnd && (isHex ? CharUtils.isHex(input.charAt(end)) : CharUtils.isAsciiNumeric(input.charAt(end)))) {
125127
end++;
126128
}
127129
final boolean semiNext = end != seqEnd && input.charAt(end) == ';';

src/test/java/org/apache/commons/lang3/text/translate/NumericEntityUnescaperTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ void testSupplementaryUnescaping() {
5555
assertEquals(expected, result, "Failed to unescape numeric entities supplementary characters");
5656
}
5757

58+
@Test
59+
void testDecimalEntityFollowedByHexLetter() {
60+
// A decimal entity ends at the first non-decimal character, so a following a-f letter is text, not part of the number.
61+
final NumericEntityUnescaper neu = new NumericEntityUnescaper(NumericEntityUnescaper.OPTION.semiColonOptional);
62+
assertEquals("0abc", neu.translate("&#48abc"), "Failed to stop a decimal entity at a trailing hex letter");
63+
assertEquals("Test 0 not test", neu.translate("Test &#48 not test"), "Failed on a decimal entity terminated by a space");
64+
assertEquals("0xyz", neu.translate("&#48xyz"), "Failed on a decimal entity terminated by a non-hex letter");
65+
}
66+
5867
@Test
5968
void testUnfinishedEntity() {
6069
// parse it

0 commit comments

Comments
 (0)