ICU-21419 Fix memory leak in AliasReplacer
diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp
index 7b259da..a210424 100644
--- a/icu4c/source/common/locid.cpp
+++ b/icu4c/source/common/locid.cpp
@@ -1410,7 +1410,7 @@
.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 @@
*(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;
diff --git a/icu4c/source/test/intltest/loctest.cpp b/icu4c/source/test/intltest/loctest.cpp
index 4bb402c..0886cc7 100644
--- a/icu4c/source/test/intltest/loctest.cpp
+++ b/icu4c/source/test/intltest/loctest.cpp
@@ -281,6 +281,7 @@
TESTCASE_AUTO(TestSetUnicodeKeywordValueInLongLocale);
TESTCASE_AUTO(TestSetUnicodeKeywordValueNullInLongLocale);
TESTCASE_AUTO(TestCanonicalize);
+ TESTCASE_AUTO(TestLeak21419);
TESTCASE_AUTO_END;
}
@@ -6406,3 +6407,9 @@
}
}
}
+
+void LocaleTest::TestLeak21419() {
+ IcuTestErrorCode status(*this, "TestLeak21419");
+ Locale l = Locale("s-yU");
+ l.canonicalize(status);
+}
diff --git a/icu4c/source/test/intltest/loctest.h b/icu4c/source/test/intltest/loctest.h
index a3a1ebc..1fba6d9 100644
--- a/icu4c/source/test/intltest/loctest.h
+++ b/icu4c/source/test/intltest/loctest.h
@@ -153,6 +153,7 @@
void TestCapturingTagConvertingIterator();
void TestSetUnicodeKeywordValueInLongLocale();
void TestSetUnicodeKeywordValueNullInLongLocale();
+ void TestLeak21419();
private:
void _checklocs(const char* label,