ICU-21802 Fix error where strict date parsing could succeed on certain malformed input strings.

This commit is contained in:
Rich Gillam 2022-02-24 18:53:02 -08:00
parent a723bdf494
commit 81ad37be05
4 changed files with 44 additions and 0 deletions

View file

@ -3792,6 +3792,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
src = &text;
}
parseInt(*src, number, pos, allowNegative,currentNumberFormat);
if (!isLenient() && pos.getIndex() < start + count) {
return -start;
}
if (pos.getIndex() != parseStart) {
int32_t val = number.getLong();

View file

@ -45,6 +45,7 @@ static void TestFormatForFields(void);
static void TestForceGannenNumbering(void);
static void TestMapDateToCalFields(void);
static void TestNarrowQuarters(void);
static void TestExtraneousCharacters(void);
void addDateForTest(TestNode** root);
@ -67,6 +68,7 @@ void addDateForTest(TestNode** root)
TESTCASE(TestForceGannenNumbering);
TESTCASE(TestMapDateToCalFields);
TESTCASE(TestNarrowQuarters);
TESTCASE(TestExtraneousCharacters);
}
/* Testing the DateFormat API */
static void TestDateFormat()
@ -2017,4 +2019,24 @@ static void TestNarrowQuarters(void) {
}
}
static void TestExtraneousCharacters(void) {
// regression test for ICU-21802
UErrorCode err = U_ZERO_ERROR;
UCalendar* cal = ucal_open(u"UTC", -1, "en_US", UCAL_GREGORIAN, &err);
UDateFormat* df = udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", u"UTC", -1, u"yyyyMMdd", -1, &err);
if (assertSuccess("Failed to create date formatter and calendar", &err)) {
udat_setLenient(df, false);
udat_parseCalendar(df, cal, u"2021", -1, NULL, &err);
assertTrue("Success parsing '2021'", err == U_PARSE_ERROR);
err = U_ZERO_ERROR;
udat_parseCalendar(df, cal, u"2021-", -1, NULL, &err);
assertTrue("Success parsing '2021-'", err == U_PARSE_ERROR);
}
udat_close(df);
ucal_close(cal);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -3787,6 +3787,9 @@ public class SimpleDateFormat extends DateFormat {
} else {
number = parseInt(text, pos, allowNegative,currentNumberFormat);
}
if (!isLenient() && pos.getIndex() < start + count) {
return -start;
}
if (number != null) {
if (patternCharIndex != DateFormat.RELATED_YEAR) {
cal.set(field, number.intValue());

View file

@ -5610,4 +5610,20 @@ public class DateFormatTest extends TestFmwk {
}
}
}
@Test
public void testExtraneousCharacters() {
// regression test for ICU-21802
Calendar cal = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", ULocale.US);
df.setLenient(false);
ParsePosition pos = new ParsePosition(0);
df.parse("2021", cal, pos);
assertTrue("Success parsing '2021'", pos.getIndex() == 0);
pos.setIndex(0);
df.parse("2021-", cal, pos);
assertTrue("Success parsing '2021-'", pos.getIndex() == 0);
}
}