Skip to content

Commit d4b4d8c

Browse files
authored
Keep FastDateParser numeric parse from throwing on int overflow (#1741)
1 parent 02cc21b commit d4b4d8c

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

src/main/java/org/apache/commons/lang3/time/FastDateParser.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,15 @@ boolean parse(final FastDateParser parser, final Calendar calendar, final String
305305
pos.setErrorIndex(idx);
306306
return false;
307307
}
308-
final int value = Integer.parseInt(source.substring(pos.getIndex(), idx));
308+
final int value;
309+
try {
310+
value = Integer.parseInt(source.substring(pos.getIndex(), idx));
311+
} catch (final NumberFormatException nfe) {
312+
// A run of digits that overflows int cannot be represented by this field; signal a parse failure
313+
// rather than letting NumberFormatException escape the ParsePosition-based parse methods.
314+
pos.setErrorIndex(pos.getIndex());
315+
return false;
316+
}
309317
pos.setIndex(idx);
310318
calendar.set(field, modify(parser, value));
311319
return true;

src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.jupiter.api.Assertions.assertFalse;
2222
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2323
import static org.junit.jupiter.api.Assertions.assertNotNull;
24+
import static org.junit.jupiter.api.Assertions.assertNull;
2425
import static org.junit.jupiter.api.Assertions.assertThrows;
2526
import static org.junit.jupiter.api.Assertions.assertTrue;
2627
import static org.junit.jupiter.api.Assertions.fail;
@@ -411,6 +412,20 @@ void testLang1121(final TriFunction<String, TimeZone, Locale, DateParser> dpProv
411412
assertEquals(expected, actual);
412413
}
413414

415+
@ParameterizedTest
416+
@MethodSource(DATE_PARSER_PARAMETERS)
417+
void testLang1359(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) {
418+
// A trailing numeric field is unbounded, so a digit run that overflows int must fail the parse
419+
// through the ParsePosition/ParseException contract, not escape as a NumberFormatException.
420+
final DateParser fdp = getInstance(dpProvider, "yyyy", TimeZones.GMT, Locale.US);
421+
final String overflow = "99999999999";
422+
assertThrows(ParseException.class, () -> fdp.parse(overflow));
423+
final ParsePosition pos = new ParsePosition(0);
424+
assertNull(fdp.parseObject(overflow, pos));
425+
assertTrue(pos.getErrorIndex() >= 0);
426+
assertEquals(0, pos.getIndex());
427+
}
428+
414429
@ParameterizedTest
415430
@MethodSource(DATE_PARSER_PARAMETERS)
416431
void testLang1380(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider) throws ParseException {

0 commit comments

Comments
 (0)