From 9668c7c2f0a767fb5ef4414a1cba43b360a06563 Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Tue, 29 Aug 2023 22:49:52 +0000 Subject: [PATCH] ICU-22475 Fix double free in Locale under OOM See #2567 --- icu4c/source/common/uloc_tag.cpp | 5 +++-- icu4c/source/test/cintltst/cloctst.c | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/icu4c/source/common/uloc_tag.cpp b/icu4c/source/common/uloc_tag.cpp index 43d597549f77..8f3778be565a 100644 --- a/icu4c/source/common/uloc_tag.cpp +++ b/icu4c/source/common/uloc_tag.cpp @@ -2092,12 +2092,13 @@ ultag_parse(const char* tag, int32_t tagLen, int32_t* parsedLen, UErrorCode* sta int32_t oldTagLength = tagLen; if (tagLen < newTagLength) { uprv_free(tagBuf); - tagBuf = (char*)uprv_malloc(newTagLength + 1); + // Change t->buf after the free and before return to avoid the second double free in + // the destructor of t when t is out of scope. + t->buf = tagBuf = (char*)uprv_malloc(newTagLength + 1); if (tagBuf == nullptr) { *status = U_MEMORY_ALLOCATION_ERROR; return nullptr; } - t->buf = tagBuf; tagLen = newTagLength; } parsedLenDelta = checkLegacyLen - replacementLen; diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index 42fabefa664f..9490431cd8a5 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -2508,6 +2508,10 @@ static void TestCanonicalization21749StackUseAfterScope(void) input, u_errorName(status)); return; } + + // ICU-22475 test that we don't free an internal buffer twice. + status = U_ZERO_ERROR; + uloc_canonicalize("ti-defaultgR-lS-z-UK-0P", buffer, UPRV_LENGTHOF(buffer), &status); } static void TestDisplayKeywords(void)