diff --git a/icu4c/source/i18n/collationbuilder.h b/icu4c/source/i18n/collationbuilder.h index a5fd8f427a42..f0c4df2b566f 100644 --- a/icu4c/source/i18n/collationbuilder.h +++ b/icu4c/source/i18n/collationbuilder.h @@ -180,26 +180,27 @@ class U_I18N_API CollationBuilder : public CollationRuleParser::Sink { * * The case bits are unused and available. */ - static inline int64_t tempCEFromIndexAndStrength(int32_t index, int32_t strength) { + static inline uint64_t tempCEFromIndexAndStrength(int32_t index, int32_t strength) { return // CE byte offsets, to ensure valid CE bytes, and case bits 11 - INT64_C(0x4040000006002000) + + UINT64_C(0x4040000006002000) + // index bits 19..13 -> primary byte 1 = CE bits 63..56 (byte values 40..BF) - (static_cast(index & 0xfe000) << 43) + + (static_cast(index & 0xfe000) << 43) + // index bits 12..6 -> primary byte 2 = CE bits 55..48 (byte values 40..BF) - (static_cast(index & 0x1fc0) << 42) + + (static_cast(index & 0x1fc0) << 42) + // index bits 5..0 -> secondary byte 1 = CE bits 31..24 (byte values 06..45) ((index & 0x3f) << 24) + // strength bits 1..0 -> tertiary byte 1 = CE bits 13..8 (byte values 20..23) (strength << 8); } - static inline int32_t indexFromTempCE(int64_t tempCE) { - tempCE -= INT64_C(0x4040000006002000); + static inline int32_t indexFromTempCE(uint64_t tempCE) { + tempCE -= UINT64_C(0x4040000006002000); return (static_cast(tempCE >> 43) & 0xfe000) | (static_cast(tempCE >> 42) & 0x1fc0) | (static_cast(tempCE >> 24) & 0x3f); } + static inline int32_t strengthFromTempCE(int64_t tempCE) { return (static_cast(tempCE) >> 8) & 3; } diff --git a/icu4c/source/test/intltest/regcoll.cpp b/icu4c/source/test/intltest/regcoll.cpp index d401d625bb76..b44bc84c0f5c 100644 --- a/icu4c/source/test/intltest/regcoll.cpp +++ b/icu4c/source/test/intltest/regcoll.cpp @@ -1249,6 +1249,12 @@ void CollationRegressionTest::TestBeforeWithTooStrongAfter() { } } +void CollationRegressionTest::TestICU23280IntOverFlow() { + UErrorCode status = U_ZERO_ERROR; + icu::LocalPointer col1( + new icu::RuleBasedCollator(u"&@<*񏼠-󏼠 ", status)); +} + void CollationRegressionTest::TestICU22555InfinityLoop() { char16_t data[] = { 0x0020, 0x0026, 0x4000, 0x002c, 0x6601, 0x0106, 0xff7f, 0xff99, @@ -1441,6 +1447,7 @@ void CollationRegressionTest::runIndexedTest(int32_t index, UBool exec, const ch TESTCASE_AUTO(TestICU22277); TESTCASE_AUTO(TestICU22517); TESTCASE_AUTO(TestICU22555InfinityLoop); + TESTCASE_AUTO(TestICU23280IntOverFlow); TESTCASE_AUTO_END; } diff --git a/icu4c/source/test/intltest/regcoll.h b/icu4c/source/test/intltest/regcoll.h index ab6575d5ecac..94e72b93032b 100644 --- a/icu4c/source/test/intltest/regcoll.h +++ b/icu4c/source/test/intltest/regcoll.h @@ -243,6 +243,7 @@ class CollationRegressionTest: public IntlTestCollator void TestICU22517(); void TestICU22555InfinityLoop(); + void TestICU23280IntOverFlow(); private: //------------------------------------------------------------------------