]> granicus.if.org Git - icu/commitdiff
ICU-21419 Fix memory leak in AliasReplacer
authorFrank Tang <ftang@chromium.org>
Tue, 1 Dec 2020 02:00:14 +0000 (18:00 -0800)
committerFrank Yung-Fong Tang <ftang@google.com>
Wed, 2 Dec 2020 18:44:45 +0000 (10:44 -0800)
icu4c/source/common/locid.cpp
icu4c/source/test/intltest/loctest.cpp
icu4c/source/test/intltest/loctest.h

index 7b259da88ce90bfa844dfc0b19e0403ec8d36335..a210424cac636dd3bda571a4ed609bc930d7e6f0 100644 (file)
@@ -1410,7 +1410,7 @@ AliasReplacer::replaceTerritory(UVector& toBeFreed, UErrorCode& status)
             .build(status);
         l.addLikelySubtags(status);
         const char* likelyRegion = l.getCountry();
-        CharString* item = nullptr;
+        LocalPointer<CharString> item;
         if (likelyRegion != nullptr && uprv_strlen(likelyRegion) > 0) {
             size_t len = uprv_strlen(likelyRegion);
             const char* foundInReplacement = uprv_strstr(replacement,
@@ -1422,20 +1422,22 @@ AliasReplacer::replaceTerritory(UVector& toBeFreed, UErrorCode& status)
                          *(foundInReplacement-1) == ' ');
                 U_ASSERT(foundInReplacement[len] == ' ' ||
                          foundInReplacement[len] == '\0');
-                item = new CharString(foundInReplacement, (int32_t)len, status);
+                item.adoptInsteadAndCheckErrorCode(
+                    new CharString(foundInReplacement, (int32_t)len, status), status);
             }
         }
-        if (item == nullptr) {
-            item = new CharString(replacement,
-                                  (int32_t)(firstSpace - replacement), status);
+        if (item.isNull() && U_SUCCESS(status)) {
+            item.adoptInsteadAndCheckErrorCode(
+                new CharString(replacement,
+                               (int32_t)(firstSpace - replacement), status), status);
         }
         if (U_FAILURE(status)) { return false; }
-        if (item == nullptr) {
+        if (item.isNull()) {
             status = U_MEMORY_ALLOCATION_ERROR;
             return false;
         }
         replacedRegion = item->data();
-        toBeFreed.addElement(item, status);
+        toBeFreed.addElement(item.orphan(), status);
     }
     U_ASSERT(!same(region, replacedRegion));
     region = replacedRegion;
index 4bb402c84e51a1086e5fa30fd615d10e12d2f5ed..0886cc72a584f44f5e640849dfb948fff410ed3c 100644 (file)
@@ -281,6 +281,7 @@ void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, c
     TESTCASE_AUTO(TestSetUnicodeKeywordValueInLongLocale);
     TESTCASE_AUTO(TestSetUnicodeKeywordValueNullInLongLocale);
     TESTCASE_AUTO(TestCanonicalize);
+    TESTCASE_AUTO(TestLeak21419);
     TESTCASE_AUTO_END;
 }
 
@@ -6406,3 +6407,9 @@ void LocaleTest::TestSetUnicodeKeywordValueNullInLongLocale() {
         }
     }
 }
+
+void LocaleTest::TestLeak21419() {
+    IcuTestErrorCode status(*this, "TestLeak21419");
+    Locale l = Locale("s-yU");
+    l.canonicalize(status);
+}
index a3a1ebc10712485341ec565e71abe29ed7c89b35..1fba6d94f564637520ed64a0a4d655bbe4b98702 100644 (file)
@@ -153,6 +153,7 @@ public:
     void TestCapturingTagConvertingIterator();
     void TestSetUnicodeKeywordValueInLongLocale();
     void TestSetUnicodeKeywordValueNullInLongLocale();
+    void TestLeak21419();
 
 private:
     void _checklocs(const char* label,