ICU-22633 Fix overflow in Chinese calendar

Fix issue found by https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=67256
This commit is contained in:
Frank Tang 2024-03-07 12:54:08 -08:00 committed by Frank Yung-Fong Tang
parent ebaf3e9f75
commit 784056dfdb
2 changed files with 21 additions and 2 deletions

View file

@ -231,9 +231,19 @@ int32_t ChineseCalendar::handleGetExtendedYear(UErrorCode& status) {
if (newestStamp(UCAL_ERA, UCAL_YEAR, kUnset) <= fStamp[UCAL_EXTENDED_YEAR]) {
year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
} else {
int32_t cycle = internalGet(UCAL_ERA, 1) - 1; // 0-based cycle
// adjust to the instance specific epoch
year = cycle * 60 + internalGet(UCAL_YEAR, 1) - (fEpochYear - CHINESE_EPOCH_YEAR);
int32_t cycle = internalGet(UCAL_ERA, 1);
year = internalGet(UCAL_YEAR, 1);
// Handle int32 overflow calculation for
// year = year + (cycle-1) * 60 -(fEpochYear - CHINESE_EPOCH_YEAR)
if (uprv_add32_overflow(cycle, -1, &cycle) || // 0-based cycle
uprv_mul32_overflow(cycle, 60, &cycle) ||
uprv_add32_overflow(year, cycle, &year) ||
uprv_add32_overflow(year, -(fEpochYear-CHINESE_EPOCH_YEAR),
&year)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
}
return year;
}

View file

@ -5650,6 +5650,15 @@ void CalendarTest::Test22633ChineseOverflow() {
cal->set(UCAL_EXTENDED_YEAR, -1594662558);
cal->get(UCAL_YEAR, status);
assertTrue("Should return success", U_SUCCESS(status));
cal->setTime(17000065021099877464213620139773683829419175940649608600213244013003611130029599692535053209683880603725167923910423116397083334648012657787978113960494455603744210944.000000, status);
cal->add(UCAL_YEAR, 1935762034, status);
assertTrue("Should return falure", U_FAILURE(status));
status = U_ZERO_ERROR;
cal->set(UCAL_ERA, 1651667877);
cal->add(UCAL_YEAR, 1935762034, status);
assertTrue("Should return falure", U_FAILURE(status));
}
void CalendarTest::Test22633IndianOverflow() {
UErrorCode status = U_ZERO_ERROR;