Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICU-20558 Fix regression in DateTimePatternGenerator (Backport for 63) #635

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions icu4c/source/i18n/dtptngen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ void
DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err) {
destination.clear().append(DT_DateTimeGregorianTag, -1, err); // initial default
if ( U_SUCCESS(err) ) {
UErrorCode localStatus = U_ZERO_ERROR;
char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY];
// obtain a locale that always has the calendar key value that should be used
ures_getFunctionalEquivalent(
Expand All @@ -767,8 +768,7 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString&
locale.getName(),
nullptr,
FALSE,
&err);
if (U_FAILURE(err)) { return; }
&localStatus);
localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination
// now get the calendar key value from that locale
char calendarType[ULOC_KEYWORDS_CAPACITY];
Expand All @@ -777,13 +777,17 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString&
"calendar",
calendarType,
ULOC_KEYWORDS_CAPACITY,
&err);
if (U_FAILURE(err)) { return; }
&localStatus);
// If the input locale was invalid, don't fail with missing resource error, instead
// continue with default of Gregorian.
if (U_FAILURE(localStatus) && localStatus != U_MISSING_RESOURCE_ERROR) {
err = localStatus;
return;
}
if (calendarTypeLen < ULOC_KEYWORDS_CAPACITY) {
destination.clear().append(calendarType, -1, err);
if (U_FAILURE(err)) { return; }
}
err = U_ZERO_ERROR;
}
}

Expand Down
30 changes: 29 additions & 1 deletion icu4c/source/test/intltest/dtptngts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
#include "unicode/dtptngen.h"
#include "unicode/ustring.h"
#include "cmemory.h"
#include "cstring.h"
#include "loctest.h"


// This is an API test, not a unit test. It doesn't test very many cases, and doesn't
// try to test the full functionality. It just calls each function in the class and
// verifies that it works on a basic level.
Expand All @@ -38,6 +38,7 @@ void IntlTestDateTimePatternGeneratorAPI::runIndexedTest( int32_t index, UBool e
TESTCASE(4, testC);
TESTCASE(5, testSkeletonsWithDayPeriods);
TESTCASE(6, testGetFieldDisplayNames);
TESTCASE(7, testFallbackWithDefaultRootLocale);
default: name = ""; break;
}
}
Expand Down Expand Up @@ -1259,4 +1260,31 @@ void IntlTestDateTimePatternGeneratorAPI::testGetFieldDisplayNames() {
}
}

void IntlTestDateTimePatternGeneratorAPI::testFallbackWithDefaultRootLocale() {
UErrorCode status = U_ZERO_ERROR;
char original[ULOC_FULLNAME_CAPACITY];

uprv_strcpy(original, uloc_getDefault());
uloc_setDefault("root", &status);
if (U_FAILURE(status)) {
errln("ERROR: Failed to change the default locale to root! Default is: %s\n", uloc_getDefault());
}

DateTimePatternGenerator* dtpg = icu::DateTimePatternGenerator::createInstance("abcdedf", status);

if (U_FAILURE(status)) {
errln("ERROR: expected createInstance with invalid locale to succeed. Status: %s", u_errorName(status));
}
if (status != U_USING_DEFAULT_WARNING) {
errln("ERROR: expected createInstance to return U_USING_DEFAULT_WARNING for invalid locale and default root locale. Status: %s", u_errorName(status));
}

delete dtpg;

uloc_setDefault(original, &status);
if (U_FAILURE(status)) {
errln("ERROR: Failed to change the default locale back to %s\n", original);
}
}

#endif /* #if !UCONFIG_NO_FORMATTING */
1 change: 1 addition & 0 deletions icu4c/source/test/intltest/dtptngts.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class IntlTestDateTimePatternGeneratorAPI : public IntlTest {
void testC();
void testSkeletonsWithDayPeriods();
void testGetFieldDisplayNames();
void testFallbackWithDefaultRootLocale();
};

#endif /* #if !UCONFIG_NO_FORMATTING */
Expand Down