From 44ea9278b97768ee8c5df9d247f9afd43be1ed52 Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Fri, 8 Nov 2024 00:13:30 -0800 Subject: [PATCH] ICU-22962 fix int32_t overflow inside handleComputeJulianDay test --- icu4c/source/i18n/calendar.cpp | 7 ++++++- icu4c/source/test/intltest/caltest.cpp | 12 ++++++++++++ icu4c/source/test/intltest/caltest.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index e713fb0195ed..c3643a986896 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -3609,7 +3609,12 @@ int32_t Calendar::handleComputeJulianDay(UCalendarDateFields bestField, UErrorCo #endif if(julianDay+testDate > nextJulianDay) { // is it past Dec 31? (nextJulianDay is day BEFORE year+1's Jan 1) // Fire up the calculating engines.. retry YWOY = (year-1) - julianDay = handleComputeMonthStart(year-1, 0, false, status); // jd before Jan 1 of previous year + int32_t prevYear; + if (uprv_add32_overflow(year, -1, &prevYear)) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + julianDay = handleComputeMonthStart(prevYear, 0, false, status); // jd before Jan 1 of previous year if (U_FAILURE(status)) { return 0; } diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index 00485c30de6d..ca3597c3f02a 100644 --- a/icu4c/source/test/intltest/caltest.cpp +++ b/icu4c/source/test/intltest/caltest.cpp @@ -207,6 +207,7 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, TESTCASE_AUTO(Test22633HebrewLargeNegativeDay); TESTCASE_AUTO(Test22730JapaneseOverflow); TESTCASE_AUTO(Test22730CopticOverflow); + TESTCASE_AUTO(Test22962ComputeJulianDayOverflow); TESTCASE_AUTO(TestAddOverflow); @@ -5898,6 +5899,17 @@ void CalendarTest::Test22730CopticOverflow() { assertEquals("status return without overflow", status, U_ILLEGAL_ARGUMENT_ERROR); } +void CalendarTest::Test22962ComputeJulianDayOverflow() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer calendar( + Calendar::createInstance(Locale("nds-NL-u-ca-islamic-umalqura"), status), + status); + calendar->clear(); + calendar->set(UCAL_YEAR, -2147483648); + calendar->set(UCAL_WEEK_OF_YEAR, 33816240); + calendar->get(UCAL_ERA, status); + assertEquals("status return without overflow", status, U_ILLEGAL_ARGUMENT_ERROR); +} void CalendarTest::TestAddOverflow() { UErrorCode status = U_ZERO_ERROR; diff --git a/icu4c/source/test/intltest/caltest.h b/icu4c/source/test/intltest/caltest.h index defb40508cc9..5795a176d72a 100644 --- a/icu4c/source/test/intltest/caltest.h +++ b/icu4c/source/test/intltest/caltest.h @@ -348,6 +348,7 @@ class CalendarTest: public CalendarTimeZoneTest { void Test22633RollTwiceGetTimeOverflow(); void Test22730JapaneseOverflow(); void Test22730CopticOverflow(); + void Test22962ComputeJulianDayOverflow(); void Test22750Roll();