Skip to content

Commit

Permalink
ICU-21810 Fix memory allocation error check
Browse files Browse the repository at this point in the history
  • Loading branch information
FrankYFTang committed Jun 13, 2024
1 parent b82291f commit 5e1576c
Showing 1 changed file with 50 additions and 5 deletions.
55 changes: 50 additions & 5 deletions icu4c/source/common/ucurr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,9 @@ toUpperCase(const char16_t* source, int32_t len, const char* locale) {

ec = U_ZERO_ERROR;
dest = (char16_t*)uprv_malloc(sizeof(char16_t) * MAX(destLen, len));
if (dest == nullptr) {
return nullptr;
}
u_strToUpper(dest, destLen, source, len, locale, &ec);
if (U_FAILURE(ec)) {
u_memcpy(dest, source, len);
Expand All @@ -946,6 +949,7 @@ toUpperCase(const char16_t* source, int32_t len, const char* locale) {
}


static void deleteCurrencyNames(CurrencyNameStruct* currencyNames, int32_t count);
// Collect all available currency names associated with the given locale
// (enable fallback chain).
// Read currenc names defined in resource bundle "Currencies" and
Expand All @@ -959,6 +963,9 @@ collectCurrencyNames(const char* locale,
CurrencyNameStruct** currencySymbols,
int32_t* total_currency_symbol_count,
UErrorCode& ec) {
if (U_FAILURE(ec)) {
return;
}
U_NAMESPACE_USE
const icu::Hashtable *currencySymbolsEquiv = getCurrSymbolsEquiv();
// Look up the Currencies resource for the given locale.
Expand All @@ -967,22 +974,30 @@ collectCurrencyNames(const char* locale,
CharString loc = ulocimp_getName(locale, ec2);
if (U_FAILURE(ec2)) {
ec = U_ILLEGAL_ARGUMENT_ERROR;
return;
}

// Get maximum currency name count first.
getCurrencyNameCount(loc.data(), total_currency_name_count, total_currency_symbol_count);

*currencySymbols = nullptr;
*currencyNames = (CurrencyNameStruct*)uprv_malloc
(sizeof(CurrencyNameStruct) * (*total_currency_name_count));
if(*currencyNames == nullptr) {
*total_currency_name_count = *total_currency_symbol_count = 0;
ec = U_MEMORY_ALLOCATION_ERROR;
return;
}
*currencySymbols = (CurrencyNameStruct*)uprv_malloc
(sizeof(CurrencyNameStruct) * (*total_currency_symbol_count));

if(currencyNames == nullptr || currencySymbols == nullptr) {
ec = U_MEMORY_ALLOCATION_ERROR;
if(*currencySymbols == nullptr) {
*total_currency_name_count = *total_currency_symbol_count = 0;
uprv_free(*currencyNames);
ec = U_MEMORY_ALLOCATION_ERROR;
return;
}

if (U_FAILURE(ec)) return;

const char16_t* s = nullptr; // currency name
char* iso = nullptr; // currency ISO code

Expand Down Expand Up @@ -1028,12 +1043,19 @@ collectCurrencyNames(const char* locale,
// Add currency long name.
s = ures_getStringByIndex(names.getAlias(), UCURR_LONG_NAME, &len, &ec2);
char16_t* upperName = toUpperCase(s, len, locale);

if (upperName == nullptr) {
ec = U_MEMORY_ALLOCATION_ERROR;
goto error;
}
(*currencyNames)[(*total_currency_name_count)++] = {iso, upperName, len, NEED_TO_BE_DELETED};

// put (iso, 3, and iso) in to array
// Add currency ISO code.
char16_t* isoCode = (char16_t*)uprv_malloc(sizeof(char16_t)*3);
if (isoCode == nullptr) {
ec = U_MEMORY_ALLOCATION_ERROR;
goto error;
}
// Must convert iso[] into Unicode
u_charsToUChars(iso, isoCode, 3);
(*currencySymbols)[(*total_currency_symbol_count)++] = {iso, isoCode, 3, NEED_TO_BE_DELETED};
Expand All @@ -1058,6 +1080,10 @@ collectCurrencyNames(const char* locale,
// currency long name?
s = ures_getStringByIndex(names.getAlias(), j, &len, &ec5);
char16_t* upperName = toUpperCase(s, len, locale);
if (upperName == nullptr) {
ec = U_MEMORY_ALLOCATION_ERROR;
goto error;
}
(*currencyNames)[(*total_currency_name_count)++] = {iso, upperName, len, NEED_TO_BE_DELETED};
}
}
Expand Down Expand Up @@ -1101,6 +1127,15 @@ collectCurrencyNames(const char* locale,
} else if (U_FAILURE(ec4)) {
ec = ec4;
}

error:
// clean up if we got error
if (U_FAILURE(ec)) {
deleteCurrencyNames(*currencyNames, *total_currency_name_count);
deleteCurrencyNames(*currencySymbols, *total_currency_symbol_count);
*currencyNames = *currencySymbols = nullptr;
*total_currency_name_count = *total_currency_symbol_count = 0;
}
}

// @param currencyNames: currency names array
Expand Down Expand Up @@ -1434,6 +1469,12 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
}
}
cacheEntry = (CurrencyNameCacheEntry*)uprv_malloc(sizeof(CurrencyNameCacheEntry));
if (cacheEntry == nullptr) {
deleteCurrencyNames(currencyNames, total_currency_name_count);
deleteCurrencyNames(currencySymbols, total_currency_symbol_count);
ec = U_MEMORY_ALLOCATION_ERROR;
return nullptr;
}
currCache[currentCacheEntryIndex] = cacheEntry;
uprv_strcpy(cacheEntry->locale, locale);
cacheEntry->currencyNames = currencyNames;
Expand Down Expand Up @@ -2584,6 +2625,10 @@ U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key,
while ((value = (char *)ulist_getNext(otherValues)) != nullptr) {
if (!ulist_containsString(values, value, (int32_t)uprv_strlen(value))) {
char *tmpValue = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY);
if (tmpValue == nullptr) {
*status = U_MEMORY_ALLOCATION_ERROR;
break;
}
uprv_memcpy(tmpValue, value, uprv_strlen(value) + 1);
ulist_addItemEndList(values, tmpValue, true, status);
if (U_FAILURE(*status)) {
Expand Down

0 comments on commit 5e1576c

Please sign in to comment.