From 0112e4292e5293c6211471a131552469ad6f9595 Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Tue, 4 Feb 2025 11:17:44 -0800 Subject: [PATCH] ICU-22962 Fix int32_t overflow issue when month is large --- icu4c/source/i18n/calendar.cpp | 7 ++++++- icu4c/source/test/intltest/caltest.cpp | 16 ++++++++++++++++ icu4c/source/test/intltest/caltest.h | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index 167d8644827..d023b096d3a 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -3804,7 +3804,12 @@ int32_t Calendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t w int32_t Calendar::handleGetMonthLength(int32_t extendedYear, int32_t month, UErrorCode& status) const { - return handleComputeMonthStart(extendedYear, month+1, true, status) - + int32_t nextMonth; + if (uprv_add32_overflow(month, 1, &nextMonth)) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + return handleComputeMonthStart(extendedYear, nextMonth, true, status) - handleComputeMonthStart(extendedYear, month, true, status); } diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index d5a824ec6fa..90d3dba2eb4 100644 --- a/icu4c/source/test/intltest/caltest.cpp +++ b/icu4c/source/test/intltest/caltest.cpp @@ -217,6 +217,7 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, TESTCASE_AUTO(Test22750Roll); TESTCASE_AUTO(TestChineseCalendarComputeMonthStart); + TESTCASE_AUTO(Test22962MonthAddOneOverflow); TESTCASE_AUTO_END; } @@ -6004,6 +6005,21 @@ void CalendarTest::TestAddOverflow() { } } +void CalendarTest::Test22962MonthAddOneOverflow() { + Locale locale("ckb_IQ@calendar=ethiopic-amete-alem"); + UErrorCode status = U_ZERO_ERROR; + LocalPointer cal(Calendar::createInstance( + *TimeZone::getGMT(), locale, status)); + cal->clear(); + status = U_ZERO_ERROR; + cal->fieldDifference( + (double)115177509667085876226560460721710683457425563915331054206329829993967720136006086546037257220523631494518538798239249720325557586193565921621016454170342731307548672.0, + UCAL_MONTH, status); + status = U_ZERO_ERROR; + cal->set(UCAL_DAY_OF_WEEK_IN_MONTH , -2111799174); + cal->add(UCAL_ERA, -1426056846, status); + assertTrue("Should return failure", U_FAILURE(status)); +} void CalendarTest::Test22750Roll() { UErrorCode status = U_ZERO_ERROR; Locale l(Locale::getRoot()); diff --git a/icu4c/source/test/intltest/caltest.h b/icu4c/source/test/intltest/caltest.h index e1a505292e5..c75b73464a0 100644 --- a/icu4c/source/test/intltest/caltest.h +++ b/icu4c/source/test/intltest/caltest.h @@ -352,6 +352,7 @@ public: // package void Test22730JapaneseOverflow(); void Test22730CopticOverflow(); void Test22962ComputeJulianDayOverflow(); + void Test22962MonthAddOneOverflow(); void Test22750Roll();