mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-22633 Fix hang on large negative day in hebrew calendar
Check error status and return error early in the loop
This commit is contained in:
parent
7c22ff7541
commit
6b67715a94
4 changed files with 32 additions and 1 deletions
|
@ -2368,6 +2368,7 @@ int32_t Calendar::fieldDifference(UDate targetMs, UCalendarDateFields field, UEr
|
|||
__FILE__, __LINE__, fldName(field));
|
||||
#endif
|
||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Do a binary search
|
||||
|
@ -2405,6 +2406,7 @@ int32_t Calendar::fieldDifference(UDate targetMs, UCalendarDateFields field, UEr
|
|||
__FILE__, __LINE__, fldName(field));
|
||||
#endif
|
||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -420,6 +420,9 @@ int32_t HebrewCalendar::startOfYear(int32_t year, UErrorCode &status)
|
|||
{
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_HEBREW_CALENDAR, calendar_hebrew_cleanup);
|
||||
int64_t day = CalendarCache::get(&gCache, year, status);
|
||||
if(U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (day == 0) {
|
||||
// # of months before year
|
||||
|
@ -533,7 +536,10 @@ int32_t HebrewCalendar::handleGetLimit(UCalendarDateFields field, ELimitType lim
|
|||
* Returns the length of the given month in the given year
|
||||
* @internal
|
||||
*/
|
||||
int32_t HebrewCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month, UErrorCode& /* status */) const {
|
||||
int32_t HebrewCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month, UErrorCode& status) const {
|
||||
if(U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
// Resolve out-of-range months. This is necessary in order to
|
||||
// obtain the correct year. We correct to
|
||||
// a 12- or 13-month year (add/subtract 12 or 13, depending
|
||||
|
@ -606,16 +612,25 @@ void HebrewCalendar::validateField(UCalendarDateFields field, UErrorCode &status
|
|||
* @internal
|
||||
*/
|
||||
void HebrewCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
int32_t d = julianDay - 347997;
|
||||
double m = ClockMath::floorDivide((d * (double)DAY_PARTS), (double) MONTH_PARTS); // Months (approx)
|
||||
int32_t year = (int32_t)(ClockMath::floorDivide((19. * m + 234.), 235.) + 1.); // Years (approx)
|
||||
int32_t ys = startOfYear(year, status); // 1st day of year
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
int32_t dayOfYear = (d - ys);
|
||||
|
||||
// Because of the postponement rules, it's possible to guess wrong. Fix it.
|
||||
while (dayOfYear < 1) {
|
||||
year--;
|
||||
ys = startOfYear(year, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
dayOfYear = (d - ys);
|
||||
}
|
||||
|
||||
|
|
|
@ -204,6 +204,8 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
|
|||
TESTCASE_AUTO(Test22633AddTwiceGetTimeOverflow);
|
||||
TESTCASE_AUTO(Test22633RollTwiceGetTimeOverflow);
|
||||
|
||||
TESTCASE_AUTO(Test22633HebrewLargeNegativeDay);
|
||||
|
||||
TESTCASE_AUTO(TestAddOverflow);
|
||||
|
||||
|
||||
|
@ -5863,6 +5865,17 @@ void CalendarTest::TestChineseCalendarComputeMonthStart() { // ICU-22639
|
|||
chinese.hasLeapMonthBetweenWinterSolstices);
|
||||
}
|
||||
|
||||
void CalendarTest::Test22633HebrewLargeNegativeDay() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> calendar(
|
||||
Calendar::createInstance(Locale("en-u-ca-hebrew"), status),
|
||||
status);
|
||||
calendar->clear();
|
||||
calendar->set(UCAL_DAY_OF_YEAR, -2147483648);
|
||||
calendar->get(UCAL_HOUR, status);
|
||||
assertEquals("status return without hang", status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
}
|
||||
|
||||
void CalendarTest::TestAddOverflow() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
|
|
|
@ -352,6 +352,7 @@ public: // package
|
|||
void TestFirstDayOfWeek();
|
||||
|
||||
void TestChineseCalendarComputeMonthStart();
|
||||
void Test22633HebrewLargeNegativeDay();
|
||||
|
||||
void RunChineseCalendarInTemporalLeapYearTest(Calendar* cal);
|
||||
void RunIslamicCalendarInTemporalLeapYearTest(Calendar* cal);
|
||||
|
|
Loading…
Add table
Reference in a new issue