Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions icu4c/source/i18n/collationbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int64_t>(index & 0xfe000) << 43) +
(static_cast<uint64_t>(index & 0xfe000) << 43) +
// index bits 12..6 -> primary byte 2 = CE bits 55..48 (byte values 40..BF)
(static_cast<int64_t>(index & 0x1fc0) << 42) +
(static_cast<uint64_t>(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<int32_t>(tempCE >> 43) & 0xfe000) |
(static_cast<int32_t>(tempCE >> 42) & 0x1fc0) |
(static_cast<int32_t>(tempCE >> 24) & 0x3f);
}

static inline int32_t strengthFromTempCE(int64_t tempCE) {
return (static_cast<int32_t>(tempCE) >> 8) & 3;
}
Expand Down
7 changes: 7 additions & 0 deletions icu4c/source/test/intltest/regcoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,12 @@ void CollationRegressionTest::TestBeforeWithTooStrongAfter() {
}
}

void CollationRegressionTest::TestICU23280IntOverFlow() {
UErrorCode status = U_ZERO_ERROR;
icu::LocalPointer<icu::RuleBasedCollator> col1(
new icu::RuleBasedCollator(u"&@<*񏼠-󏼠 ", status));
}

void CollationRegressionTest::TestICU22555InfinityLoop() {
char16_t data[] = {
0x0020, 0x0026, 0x4000, 0x002c, 0x6601, 0x0106, 0xff7f, 0xff99,
Expand Down Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions icu4c/source/test/intltest/regcoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ class CollationRegressionTest: public IntlTestCollator
void TestICU22517();

void TestICU22555InfinityLoop();
void TestICU23280IntOverFlow();

private:
//------------------------------------------------------------------------
Expand Down