ICU-22609 Fix nulldef w/ bogus locale in DateFormat::create*

This commit is contained in:
Frank Tang 2023-12-15 13:06:42 -08:00 committed by Frank Yung-Fong Tang
parent 5cf5ec1adb
commit 7bef50e71d
4 changed files with 29 additions and 3 deletions

View file

@ -728,16 +728,17 @@ void SimpleDateFormat::construct(EStyle timeStyle,
if (locale.getKeywordValue("rg", nullptr, 0, dummyErr1) > 0 || locale.getKeywordValue("hours", nullptr, 0, dummyErr2) > 0) {
hasRgOrHcSubtag = true;
}
const char* baseLocID = locale.getBaseName();
if (baseLocID[0]!=0 && uprv_strcmp(baseLocID,"und")!=0) {
if (baseLocID != nullptr && uprv_strcmp(baseLocID,"und")!=0) {
UErrorCode useStatus = U_ZERO_ERROR;
Locale baseLoc(baseLocID);
Locale validLoc(getLocale(ULOC_VALID_LOCALE, useStatus));
if (hasRgOrHcSubtag || (U_SUCCESS(useStatus) && validLoc!=baseLoc)) {
bool useDTPG = hasRgOrHcSubtag;
const char* baseReg = baseLoc.getCountry(); // empty string if no region
if ((baseReg[0]!=0 && uprv_strncmp(baseReg,validLoc.getCountry(),ULOC_COUNTRY_CAPACITY)!=0)
if ((baseReg != nullptr && baseReg[0] != 0 &&
uprv_strncmp(baseReg,validLoc.getCountry(),ULOC_COUNTRY_CAPACITY)!=0)
|| uprv_strncmp(baseLoc.getLanguage(),validLoc.getLanguage(),ULOC_LANG_CAPACITY)!=0) {
// use DTPG if
// * baseLoc has a region and validLoc does not have the same one (or has none), OR

View file

@ -51,6 +51,7 @@ static void TestNarrowQuarters(void);
static void TestExtraneousCharacters(void);
static void TestParseTooStrict(void);
static void TestHourCycle(void);
static void TestLocaleNameCrash(void);
void addDateForTest(TestNode** root);
@ -76,6 +77,7 @@ void addDateForTest(TestNode** root)
TESTCASE(TestExtraneousCharacters);
TESTCASE(TestParseTooStrict);
TESTCASE(TestHourCycle);
TESTCASE(TestLocaleNameCrash);
}
/* Testing the DateFormat API */
static void TestDateFormat()
@ -2129,4 +2131,17 @@ static void TestHourCycle(void) {
}
}
static void TestLocaleNameCrash(void) {
UErrorCode status = U_ZERO_ERROR;
UDateFormat icudf;
icudf = udat_open(UDAT_MEDIUM, UDAT_NONE, "notalanguage", NULL, 0, NULL, 0, &status);
if ( U_SUCCESS(status) ) {
log_verbose("Success: did not crash on udat_open(locale=\"notalanguage\")\n");
} else {
log_err("FAIL: didn't crash on udat_open(locale=\"notalanguage\"), but got %s.\n", u_errorName(status));
}
udat_close(icudf);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -135,6 +135,7 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam
TESTCASE_AUTO(TestNumericFieldStrictParse);
TESTCASE_AUTO(TestHourCycle);
TESTCASE_AUTO(TestHCInLocale);
TESTCASE_AUTO(TestBogusLocale);
TESTCASE_AUTO_END;
}
@ -5876,6 +5877,14 @@ void DateFormatTest::TestHourCycle() {
}
}
void DateFormatTest::TestBogusLocale() {
IcuTestErrorCode status(*this, "TestBogusLocale");
LocalPointer<DateFormat> df;
df.adoptInstead(DateFormat::createDateTimeInstance(DateFormat::kNone, DateFormat::kMedium,
Locale("notalanguage")));
}
void DateFormatTest::TestHCInLocale() {
IcuTestErrorCode status(*this, "TestHCInLocale");
LocalPointer<Calendar> midnight(Calendar::createInstance(status));

View file

@ -270,6 +270,7 @@ public:
void TestNumericFieldStrictParse();
void TestHourCycle();
void TestHCInLocale();
void TestBogusLocale();
private:
UBool showParse(DateFormat &format, const UnicodeString &formattedString);