ICU-12407 Prevent parse crash in DECIMAL-style formatter with applied currency pattern
X-SVN-Rev: 39236
This commit is contained in:
parent
4e29392bdd
commit
e02cfd9eac
@ -447,13 +447,25 @@ DecimalFormat::construct(UErrorCode& status,
|
||||
if (patternUsed->indexOf(kCurrencySign) != -1) {
|
||||
// initialize for currency, not only for plural format,
|
||||
// but also for mix parsing
|
||||
if (fCurrencyPluralInfo == NULL) {
|
||||
fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// need it for mix parsing
|
||||
handleCurrencySignInPattern(status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DecimalFormat::handleCurrencySignInPattern(UErrorCode& status) {
|
||||
// initialize for currency, not only for plural format,
|
||||
// but also for mix parsing
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
if (fCurrencyPluralInfo == NULL) {
|
||||
fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// need it for mix parsing
|
||||
if (fAffixPatternsForCurrency == NULL) {
|
||||
setupCurrencyAffixPatterns(status);
|
||||
}
|
||||
}
|
||||
@ -2817,6 +2829,9 @@ DecimalFormat::toLocalizedPattern(UnicodeString& result) const
|
||||
void
|
||||
DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
|
||||
{
|
||||
if (pattern.indexOf(kCurrencySign) != -1) {
|
||||
handleCurrencySignInPattern(status);
|
||||
}
|
||||
fImpl->applyPattern(pattern, status);
|
||||
}
|
||||
|
||||
@ -2827,6 +2842,9 @@ DecimalFormat::applyPattern(const UnicodeString& pattern,
|
||||
UParseError& parseError,
|
||||
UErrorCode& status)
|
||||
{
|
||||
if (pattern.indexOf(kCurrencySign) != -1) {
|
||||
handleCurrencySignInPattern(status);
|
||||
}
|
||||
fImpl->applyPattern(pattern, parseError, status);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
@ -2834,6 +2852,9 @@ DecimalFormat::applyPattern(const UnicodeString& pattern,
|
||||
void
|
||||
DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
|
||||
{
|
||||
if (pattern.indexOf(kCurrencySign) != -1) {
|
||||
handleCurrencySignInPattern(status);
|
||||
}
|
||||
fImpl->applyLocalizedPattern(pattern, status);
|
||||
}
|
||||
|
||||
@ -2844,6 +2865,9 @@ DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
|
||||
UParseError& parseError,
|
||||
UErrorCode& status)
|
||||
{
|
||||
if (pattern.indexOf(kCurrencySign) != -1) {
|
||||
handleCurrencySignInPattern(status);
|
||||
}
|
||||
fImpl->applyLocalizedPattern(pattern, parseError, status);
|
||||
}
|
||||
|
||||
|
@ -2103,6 +2103,8 @@ private:
|
||||
DecimalFormatSymbols* symbolsToAdopt = 0
|
||||
);
|
||||
|
||||
void handleCurrencySignInPattern(UErrorCode& status);
|
||||
|
||||
void parse(const UnicodeString& text,
|
||||
Formattable& result,
|
||||
ParsePosition& pos,
|
||||
|
@ -62,6 +62,7 @@ static void TestContext(void);
|
||||
static void TestCurrencyUsage(void);
|
||||
static void TestCurrFmtNegSameAsPositive(void);
|
||||
static void TestVariousStylesAndAttributes(void);
|
||||
static void TestParseCurrPatternWithDecStyle(void);
|
||||
|
||||
#define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x)
|
||||
|
||||
@ -91,6 +92,7 @@ void addNumForTest(TestNode** root)
|
||||
TESTCASE(TestCurrencyUsage);
|
||||
TESTCASE(TestCurrFmtNegSameAsPositive);
|
||||
TESTCASE(TestVariousStylesAndAttributes);
|
||||
TESTCASE(TestParseCurrPatternWithDecStyle);
|
||||
}
|
||||
|
||||
/* test Parse int 64 */
|
||||
@ -2862,4 +2864,27 @@ static void TestVariousStylesAndAttributes(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static const UChar currpat[] = { 0xA4,0x23,0x2C,0x23,0x23,0x30,0x2E,0x30,0x30,0}; /* ¤#,##0.00 */
|
||||
static const UChar parsetxt[] = { 0x78,0x30,0x79,0x24,0 }; /* x0y$ */
|
||||
|
||||
static void TestParseCurrPatternWithDecStyle() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UNumberFormat *unumfmt = unum_open(UNUM_DECIMAL, NULL, 0, "en_US", NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_data_err("unum_open DECIMAL failed for en_US: %s (Are you missing data?)\n", u_errorName(status));
|
||||
} else {
|
||||
unum_applyPattern(unumfmt, FALSE, currpat, -1, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err_status(status, "unum_applyPattern failed: %s\n", u_errorName(status));
|
||||
} else {
|
||||
int32_t pos = 0;
|
||||
double value = unum_parseDouble(unumfmt, parsetxt, -1, &pos, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
log_err_status(status, "unum_parseDouble expected to fail but got status %s, value %f\n", u_errorName(status), value);
|
||||
}
|
||||
}
|
||||
unum_close(unumfmt);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
Loading…
Reference in New Issue
Block a user