ICU-13850 Fixing behavior of ICU4C DecimalFormat#setCurrency() to accept an empty string.
X-SVN-Rev: 41549
diff --git a/icu4c/source/i18n/currunit.cpp b/icu4c/source/i18n/currunit.cpp
index 3de6856..bd60593 100644
--- a/icu4c/source/i18n/currunit.cpp
+++ b/icu4c/source/i18n/currunit.cpp
@@ -27,8 +27,9 @@
// 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?
diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp
index b718429..ffc1e83 100644
--- a/icu4c/source/test/intltest/numfmtst.cpp
+++ b/icu4c/source/test/intltest/numfmtst.cpp
@@ -216,6 +216,7 @@
TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode);
TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing);
TESTCASE_AUTO(Test13840_ParseLongStringCrash);
+ TESTCASE_AUTO(Test13850_EmptyStringCurrency);
TESTCASE_AUTO_END;
}
@@ -9185,4 +9186,25 @@
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 */
diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h
index b51e752..9f7a5c0 100644
--- a/icu4c/source/test/intltest/numfmtst.h
+++ b/icu4c/source/test/intltest/numfmtst.h
@@ -280,6 +280,7 @@
void Test13777_ParseLongNameNonCurrencyMode();
void Test13804_EmptyStringsWhenParsing();
void Test13840_ParseLongStringCrash();
+ void Test13850_EmptyStringCurrency();
private:
UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f);