ICU-20044 Fix some OOM issues in the NumberFormat class. (#21)

This commit is contained in:
Jeff Genovy 2018-08-02 00:09:14 -07:00 committed by Shane Carr
parent 8edc6ba107
commit a9a19fc229
No known key found for this signature in database
GPG Key ID: FCED3B24AAB18B5C

View File

@ -1326,13 +1326,13 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
// if the locale has "@compat=host", create a host-specific NumberFormat
if (U_SUCCESS(status) && count > 0 && uprv_strcmp(buffer, "host") == 0) {
Win32NumberFormat *f = NULL;
UBool curr = TRUE;
switch (style) {
case UNUM_DECIMAL:
curr = FALSE;
// fall-through
U_FALLTHROUGH;
case UNUM_CURRENCY:
case UNUM_CURRENCY_ISO: // do not support plural formatting here
@ -1340,14 +1340,13 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
case UNUM_CURRENCY_ACCOUNTING:
case UNUM_CASH_CURRENCY:
case UNUM_CURRENCY_STANDARD:
f = new Win32NumberFormat(desiredLocale, curr, status);
{
LocalPointer<Win32NumberFormat> f(new Win32NumberFormat(desiredLocale, curr, status), status);
if (U_SUCCESS(status)) {
return f;
return f.orphan();
}
delete f;
break;
}
break;
default:
break;
}
@ -1417,8 +1416,7 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
}
}
NumberFormat *f;
LocalPointer<NumberFormat> f;
if (ns->isAlgorithmic()) {
UnicodeString nsDesc;
UnicodeString nsRuleSetGroup;
@ -1453,7 +1451,7 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
return NULL;
}
r->setDefaultRuleSet(nsRuleSetName,status);
f = r;
f.adoptInstead(r);
} else {
// replace single currency sign in the pattern with double currency sign
// if the style is UNUM_CURRENCY_ISO
@ -1462,9 +1460,22 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
UnicodeString(TRUE, gDoubleCurrencySign, 2));
}
// "new DecimalFormat()" does not adopt the symbols if its memory allocation fails.
DecimalFormatSymbols *syms = symbolsToAdopt.orphan();
DecimalFormat* df = new DecimalFormat(pattern, syms, style, status);
// "new DecimalFormat()" does not adopt the symbols argument if its memory allocation fails.
// So we can't use adoptInsteadAndCheckErrorCode as we need to know if the 'new' failed.
DecimalFormatSymbols *syms = symbolsToAdopt.getAlias();
LocalPointer<DecimalFormat> df(new DecimalFormat(pattern, syms, style, status));
if (df.isValid()) {
// if the DecimalFormat object was successfully new'ed, then it will own symbolsToAdopt, even if the status is a failure.
symbolsToAdopt.orphan();
}
else {
status = U_MEMORY_ALLOCATION_ERROR;
}
if (U_FAILURE(status)) {
return nullptr;
}
// if it is cash currency style, setCurrencyUsage with usage
if (style == UNUM_CASH_CURRENCY){
@ -1472,25 +1483,18 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
}
if (U_FAILURE(status)) {
delete df;
return NULL;
return nullptr;
}
f = df;
if (f == NULL) {
delete syms;
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
f.adoptInstead(df.orphan());
}
f->setLocaleIDs(ures_getLocaleByType(ownedResource.getAlias(), ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(ownedResource.getAlias(), ULOC_ACTUAL_LOCALE, &status));
if (U_FAILURE(status)) {
delete f;
return NULL;
}
return f;
return f.orphan();
}
/**