From 1ec55bf021c8eba406001c82981644655b745e53 Mon Sep 17 00:00:00 2001 From: Rich Gillam <62772518+richgillam@users.noreply.github.com> Date: Mon, 19 Jul 2021 16:39:34 -0700 Subject: [PATCH] ICU-21202 Fixed error in alias resolution in uresbund.cpp. --- icu4c/source/common/uresbund.cpp | 11 ++++++++ icu4c/source/test/cintltst/udatpg_test.c | 34 ++++++++++++++++++++++++ icu4c/source/test/intltest/dtptngts.cpp | 5 ++++ 3 files changed, 50 insertions(+) diff --git a/icu4c/source/common/uresbund.cpp b/icu4c/source/common/uresbund.cpp index 3b8a654c3b6..18f474ea5fa 100644 --- a/icu4c/source/common/uresbund.cpp +++ b/icu4c/source/common/uresbund.cpp @@ -1146,6 +1146,17 @@ static UResourceBundle *init_resb_result(const ResourceData *rdata, Resource r, r = res_findResource(&(dataEntry->fData), r, &myPath, &temp); if(r != RES_BOGUS) { /* found a resource, but it might be an indirection */ resB = init_resb_result(&(dataEntry->fData), r, temp, -1, dataEntry, result, noAlias+1, resB, status); + if (temp == NULL || uprv_strcmp(keyPath, temp) != 0) { + // the call to init_resb_result() above will set resB->fKeyPath to be + // the same as resB->fKey, throwing away any additional path elements if we + // had them-- if the key path wasn't just a single resource ID, clear out + // the bundle's key path and re-set it to be equal to keyPath + ures_freeResPath(resB); + ures_appendResPath(resB, keyPath, (int32_t)uprv_strlen(keyPath), status); + if(resB->fResPath[resB->fResPathLen-1] != RES_PATH_SEPARATOR) { + ures_appendResPath(resB, RES_PATH_SEPARATOR_S, 1, status); + } + } result = resB; if(result) { r = result->fRes; /* switch to a new resource, possibly a new tree */ diff --git a/icu4c/source/test/cintltst/udatpg_test.c b/icu4c/source/test/cintltst/udatpg_test.c index 9dc72c0759a..ba427014009 100644 --- a/icu4c/source/test/cintltst/udatpg_test.c +++ b/icu4c/source/test/cintltst/udatpg_test.c @@ -45,6 +45,7 @@ static void TestOptions(void); static void TestGetFieldDisplayNames(void); static void TestGetDefaultHourCycle(void); static void TestGetDefaultHourCycleOnEmptyInstance(void); +static void TestEras(void); void addDateTimePatternGeneratorTest(TestNode** root) { TESTCASE(TestOpenClose); @@ -54,6 +55,7 @@ void addDateTimePatternGeneratorTest(TestNode** root) { TESTCASE(TestGetFieldDisplayNames); TESTCASE(TestGetDefaultHourCycle); TESTCASE(TestGetDefaultHourCycleOnEmptyInstance); + TESTCASE(TestEras); } /* @@ -580,4 +582,36 @@ static void TestGetDefaultHourCycleOnEmptyInstance() { udatpg_close(dtpgen); } +// Test for ICU-21202: Make sure DateTimePatternGenerator supplies an era field for year formats using the +// Buddhist and Japanese calendars for all English-speaking locales. +static void TestEras(void) { + const char* localeIDs[] = { + "en_US@calendar=japanese", + "en_GB@calendar=japanese", + "en_150@calendar=japanese", + "en_001@calendar=japanese", + "en@calendar=japanese", + "en_US@calendar=buddhist", + "en_GB@calendar=buddhist", + "en_150@calendar=buddhist", + "en_001@calendar=buddhist", + "en@calendar=buddhist", + }; + + UErrorCode err = U_ZERO_ERROR; + for (int32_t i = 0; i < UPRV_LENGTHOF(localeIDs); i++) { + const char* locale = localeIDs[i]; + UDateTimePatternGenerator* dtpg = udatpg_open(locale, &err); + if (U_SUCCESS(err)) { + UChar pattern[200]; + udatpg_getBestPattern(dtpg, u"y", 1, pattern, 200, &err); + + if (u_strchr(pattern, u'G') == NULL) { + log_err("missing era field for locale %s\n", locale); + } + } + udatpg_close(dtpg); + } +} + #endif diff --git a/icu4c/source/test/intltest/dtptngts.cpp b/icu4c/source/test/intltest/dtptngts.cpp index 9b0e7b5e3b3..609546204eb 100644 --- a/icu4c/source/test/intltest/dtptngts.cpp +++ b/icu4c/source/test/intltest/dtptngts.cpp @@ -1588,6 +1588,11 @@ void IntlTestDateTimePatternGeneratorAPI::testBestPattern() { "en_US", "yMMMMEEEEd", "EEEE, MMMM d, y", "en_US", "yMMMMccccd", "EEEE, MMMM d, y", "en_US", "yMMMMeeeed", "EEEE, MMMM d, y", + // ICU-21428: Bad patterns for nonstandard calendars + "en_GB", "yMd", "dd/MM/y", + "en_GB@calendar=coptic", "yMd", "dd/MM/y GGGGG", + "en_GB@calendar=japanese", "yMd", "dd/MM/y GGGGG", + "en_GB@calendar=buddhist", "yMd", "dd/MM/y GGGGG", }; for (int32_t i = 0; i < UPRV_LENGTHOF(testCases); i += 3) {