]> granicus.if.org Git - icu/commitdiff
ICU-21202 Fixed error in alias resolution in uresbund.cpp.
authorRich Gillam <62772518+richgillam@users.noreply.github.com>
Mon, 19 Jul 2021 23:39:34 +0000 (16:39 -0700)
committerRich Gillam <62772518+richgillam@users.noreply.github.com>
Wed, 18 Aug 2021 17:12:20 +0000 (10:12 -0700)
icu4c/source/common/uresbund.cpp
icu4c/source/test/cintltst/udatpg_test.c
icu4c/source/test/intltest/dtptngts.cpp

index 3b8a654c3b60879ddd717cdadac90129d6f73ca4..18f474ea5face66d5d6d90f5c68a76fb86481cd6 100644 (file)
@@ -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 */
index 9dc72c0759ad4c59a12b17b32d0ac5661dfdd1cc..ba427014009dc746c7755b892e3d66b60b3a0677 100644 (file)
@@ -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
index 9b0e7b5e3b38d77bc3f49e84d264986bf039f742..609546204ebe97d82c7d0a3ad0aa345c014669f1 100644 (file)
@@ -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) {