From a91cbd65789d69b06904d68b9dd680a80cc6d35c Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Mon, 22 Apr 2024 22:14:06 +0000 Subject: [PATCH] ICU-22750 Fix Floating-point-exception in icu::Calendar::roll See #2979 --- icu4c/source/i18n/calendar.cpp | 3 +++ icu4c/source/test/intltest/caltest.cpp | 20 ++++++++++++++++++++ icu4c/source/test/intltest/caltest.h | 3 +++ 3 files changed, 26 insertions(+) diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index 38080b4088c..87cba3b048d 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -1762,6 +1762,9 @@ void Calendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& statu { int32_t min = getActualMinimum(field,status); int32_t max = getActualMaximum(field,status); + if (U_FAILURE(status)) { + return; + } int32_t gap = max - min + 1; int64_t value = internalGet(field); diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index 79e7e974b51..8f59e4301e0 100644 --- a/icu4c/source/test/intltest/caltest.cpp +++ b/icu4c/source/test/intltest/caltest.cpp @@ -209,6 +209,7 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, TESTCASE_AUTO(TestAddOverflow); + TESTCASE_AUTO(Test22750Roll); TESTCASE_AUTO(TestChineseCalendarComputeMonthStart); @@ -5929,6 +5930,25 @@ void CalendarTest::TestAddOverflow() { } } } + +void CalendarTest::Test22750Roll() { + UErrorCode status = U_ZERO_ERROR; + Locale l(Locale::getRoot()); + std::unique_ptr enumeration( + Calendar::getKeywordValuesForLocale("calendar", l, false, status)); + // Test every calendar + for (const char* name = enumeration->next(nullptr, status); + U_SUCCESS(status) && name != nullptr; + name = enumeration->next(nullptr, status)) { + UErrorCode status2 = U_ZERO_ERROR; + l.setKeywordValue("calendar", name, status2); + LocalPointer calendar(Calendar::createInstance(l, status2)); + if (failure(status2, "Calendar::createInstance")) return; + calendar->add(UCAL_DAY_OF_WEEK_IN_MONTH, 538976288, status2); + calendar->roll(UCAL_DATE, 538976288, status2); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ //eof diff --git a/icu4c/source/test/intltest/caltest.h b/icu4c/source/test/intltest/caltest.h index b49a79d9980..cd1576a68d2 100644 --- a/icu4c/source/test/intltest/caltest.h +++ b/icu4c/source/test/intltest/caltest.h @@ -347,6 +347,9 @@ public: // package void Test22633AddTwiceGetTimeOverflow(); void Test22633RollTwiceGetTimeOverflow(); void Test22730JapaneseOverflow(); + + void Test22750Roll(); + void RunTestOnCalendars(void(TestFunc)(Calendar*, UCalendarDateFields)); void verifyFirstDayOfWeek(const char* locale, UCalendarDaysOfWeek expected);