diff --git a/icu4c/source/i18n/japancal.cpp b/icu4c/source/i18n/japancal.cpp index 7e69b97a3af4..c4873a5803cc 100644 --- a/icu4c/source/i18n/japancal.cpp +++ b/icu4c/source/i18n/japancal.cpp @@ -227,8 +227,16 @@ void JapaneseCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status int32_t year = internalGet(UCAL_EXTENDED_YEAR); // Gregorian year int32_t eraIdx = gJapaneseEraRules->getEraIndex(year, internalGetMonth(status) + 1, internalGet(UCAL_DAY_OF_MONTH), status); + int32_t startYear = gJapaneseEraRules->getStartYear(eraIdx, status) - 1; + if (U_FAILURE(status)) { + return; + } + if (uprv_add32_overflow(year, -startYear, &year)) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } internalSet(UCAL_ERA, eraIdx); - internalSet(UCAL_YEAR, year - gJapaneseEraRules->getStartYear(eraIdx, status) + 1); + internalSet(UCAL_YEAR, year); } /* diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index bace8d762f29..a104d0b8156f 100644 --- a/icu4c/source/test/intltest/caltest.cpp +++ b/icu4c/source/test/intltest/caltest.cpp @@ -205,6 +205,7 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, TESTCASE_AUTO(Test22633RollTwiceGetTimeOverflow); TESTCASE_AUTO(Test22633HebrewLargeNegativeDay); + TESTCASE_AUTO(Test22730JapaneseOverflow); TESTCASE_AUTO(TestAddOverflow); @@ -5876,6 +5877,16 @@ void CalendarTest::Test22633HebrewLargeNegativeDay() { assertEquals("status return without hang", status, U_ILLEGAL_ARGUMENT_ERROR); } +void CalendarTest::Test22730JapaneseOverflow() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer calendar( + Calendar::createInstance(Locale("en-u-ca-japanese"), status), + status); + calendar->clear(); + calendar->roll(UCAL_EXTENDED_YEAR, -1946156856, 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 eabfa8d456c8..b49a79d99801 100644 --- a/icu4c/source/test/intltest/caltest.h +++ b/icu4c/source/test/intltest/caltest.h @@ -346,6 +346,7 @@ class CalendarTest: public CalendarTimeZoneTest { void Test22633SetRollGetTimeOverflow(); void Test22633AddTwiceGetTimeOverflow(); void Test22633RollTwiceGetTimeOverflow(); + void Test22730JapaneseOverflow(); void RunTestOnCalendars(void(TestFunc)(Calendar*, UCalendarDateFields)); void verifyFirstDayOfWeek(const char* locale, UCalendarDaysOfWeek expected);