ICU-13850 Fixing behavior of ICU4C DecimalFormat#setCurrency() to accept an empty string.

X-SVN-Rev: 41549
This commit is contained in:
Shane Carr 2018-06-23 02:09:42 +00:00
parent f1d29ce62e
commit 4bc6ad328b
3 changed files with 25 additions and 1 deletions

View File

@ -27,8 +27,9 @@ CurrencyUnit::CurrencyUnit(ConstChar16Ptr _isoCode, UErrorCode& ec) {
// The constructor always leaves the CurrencyUnit in a valid state (with a 3-character currency code).
// Note: in ICU4J Currency.getInstance(), we check string length for 3, but in ICU4C we allow a
// non-NUL-terminated string to be passed as an argument, so it is not possible to check length.
// However, we allow a NUL-terminated empty string, which should have the same behavior as nullptr.
const char16_t* isoCodeToUse;
if (U_FAILURE(ec) || _isoCode == nullptr) {
if (U_FAILURE(ec) || _isoCode == nullptr || _isoCode[0] == 0) {
isoCodeToUse = kDefaultCurrency;
} else if (!uprv_isInvariantUString(_isoCode, 3)) {
// TODO: Perform a more strict ASCII check like in ICU4J isAlpha3Code?

View File

@ -216,6 +216,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode);
TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing);
TESTCASE_AUTO(Test13840_ParseLongStringCrash);
TESTCASE_AUTO(Test13850_EmptyStringCurrency);
TESTCASE_AUTO_END;
}
@ -9185,4 +9186,25 @@ void NumberFormatTest::Test13840_ParseLongStringCrash() {
assertEquals("Should round-trip without crashing", expectedUString, actualUString);
}
void NumberFormatTest::Test13850_EmptyStringCurrency() {
IcuTestErrorCode status(*this, "Test13840_EmptyStringCurrency");
LocalPointer<NumberFormat> nf(NumberFormat::createCurrencyInstance("en-US", status), status);
if (status.errIfFailureAndReset()) { return; }
UnicodeString actual;
nf->format(1, actual, status);
assertEquals("Should format with US currency", u"$1.00", actual);
nf->setCurrency(u"", status);
nf->format(1, actual.remove(), status);
assertEquals("Should unset the currency on empty string", u"XXX\u00A01.00", actual);
// Try with nullptr
nf.adoptInstead(NumberFormat::createCurrencyInstance("en-US", status));
nf->format(1, actual.remove(), status);
assertEquals("Should format with US currency", u"$1.00", actual);
nf->setCurrency(nullptr, status);
nf->format(1, actual.remove(), status);
assertEquals("Should unset the currency on nullptr", u"XXX\u00A01.00", actual);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -280,6 +280,7 @@ class NumberFormatTest: public CalendarTimeZoneTest {
void Test13777_ParseLongNameNonCurrencyMode();
void Test13804_EmptyStringsWhenParsing();
void Test13840_ParseLongStringCrash();
void Test13850_EmptyStringCurrency();
private:
UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f);