From 509405c9f2ee99a56a3fc77ba8de4799cec28d7c Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Thu, 11 Jan 2024 23:14:27 +0000 Subject: [PATCH] ICU-22626 Fix leakage when 2 '=' in PluralRules See #2782 --- icu4c/source/i18n/plurrule.cpp | 5 +++++ icu4c/source/test/intltest/plurults.cpp | 11 +++++++++++ icu4c/source/test/intltest/plurults.h | 1 + 3 files changed, 17 insertions(+) diff --git a/icu4c/source/i18n/plurrule.cpp b/icu4c/source/i18n/plurrule.cpp index 839d14147cc..b8ad0b2736f 100644 --- a/icu4c/source/i18n/plurrule.cpp +++ b/icu4c/source/i18n/plurrule.cpp @@ -656,6 +656,11 @@ PluralRuleParser::parse(const UnicodeString& ruleData, PluralRules *prules, UErr case tEqual: { U_ASSERT(curAndConstraint != nullptr); + if (curAndConstraint->rangeList != nullptr) { + // Already get a '='. + status = U_UNEXPECTED_TOKEN; + break; + } LocalPointer newRangeList(new UVector32(status), status); if (U_FAILURE(status)) { break; diff --git a/icu4c/source/test/intltest/plurults.cpp b/icu4c/source/test/intltest/plurults.cpp index 664b27f4bb7..0771baa7586 100644 --- a/icu4c/source/test/intltest/plurults.cpp +++ b/icu4c/source/test/intltest/plurults.cpp @@ -69,6 +69,7 @@ void PluralRulesTest::runIndexedTest( int32_t index, UBool exec, const char* &na TESTCASE_AUTO(testFixedDecimal); TESTCASE_AUTO(testSelectTrailingZeros); TESTCASE_AUTO(testLocaleExtension); + TESTCASE_AUTO(testDoubleEqualSign); TESTCASE_AUTO_END; } @@ -1638,6 +1639,16 @@ void PluralRulesTest::compareLocaleResults(const char* loc1, const char* loc2, c } } +void PluralRulesTest::testDoubleEqualSign() { + IcuTestErrorCode errorCode(*this, "testDoubleEqualSign"); + + // ICU-22626 + // Two '=' in the rul should not leak. + LocalPointer rules( + PluralRules::createRules(u"e:c=2=", errorCode), errorCode); + errorCode.expectErrorAndReset(U_UNEXPECTED_TOKEN); +} + void PluralRulesTest::testLocaleExtension() { IcuTestErrorCode errorCode(*this, "testLocaleExtension"); LocalPointer rules(PluralRules::forLocale("pt@calendar=gregorian", errorCode)); diff --git a/icu4c/source/test/intltest/plurults.h b/icu4c/source/test/intltest/plurults.h index 98ea9574bea..e245a44590b 100644 --- a/icu4c/source/test/intltest/plurults.h +++ b/icu4c/source/test/intltest/plurults.h @@ -50,6 +50,7 @@ private: void testFixedDecimal(); void testSelectTrailingZeros(); void testLocaleExtension(); + void testDoubleEqualSign(); void assertRuleValue(const UnicodeString& rule, double expected); void assertRuleKeyValue(const UnicodeString& rule, const UnicodeString& key,