From 42d0bab7c3ce6716472a8642c79788ed0ffd38b9 Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Tue, 18 Jun 2024 01:14:00 -0700 Subject: [PATCH] ICU-22800 Avoid inconsistent state inside Locale There are some memory leak in Locale which is hard to figure out why. Use different variable to track memory allocation to avoid inconsistent state while malloc fail --- icu4c/source/common/locid.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp index 420338c289e..8f05e23e73c 100644 --- a/icu4c/source/common/locid.cpp +++ b/icu4c/source/common/locid.cpp @@ -1869,11 +1869,11 @@ Locale& Locale::init(const char* localeID, UBool canonicalize) if(err == U_BUFFER_OVERFLOW_ERROR || length >= (int32_t)sizeof(fullNameBuffer)) { U_ASSERT(baseName == nullptr); /*Go to heap for the fullName if necessary*/ - fullName = (char *)uprv_malloc(sizeof(char)*(length + 1)); - if (fullName == nullptr) { - fullName = fullNameBuffer; + char* newFullName = (char *)uprv_malloc(sizeof(char)*(length + 1)); + if (newFullName == nullptr) { break; // error: out of memory } + fullName = newFullName; err = U_ZERO_ERROR; length = canonicalize ? uloc_canonicalize(localeID, fullName, length+1, &err) : @@ -1992,11 +1992,12 @@ Locale::initBaseName(UErrorCode &status) { if (atPtr && eqPtr && atPtr < eqPtr) { // Key words exist. int32_t baseNameLength = (int32_t)(atPtr - fullName); - baseName = (char *)uprv_malloc(baseNameLength + 1); - if (baseName == nullptr) { + char* newBaseName = (char *)uprv_malloc(baseNameLength + 1); + if (newBaseName == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; return; } + baseName = newBaseName; uprv_strncpy(baseName, fullName, baseNameLength); baseName[baseNameLength] = 0;