]> granicus.if.org Git - icu/commitdiff
ICU-22249 Fixed endless loop in ICUResourceBundle when you ask for a locale with...
authorRich Gillam <richard_gillam@apple.com>
Sat, 28 Jan 2023 02:04:35 +0000 (18:04 -0800)
committerRich Gillam <62772518+richgillam@users.noreply.github.com>
Sat, 4 Feb 2023 00:49:24 +0000 (16:49 -0800)
is also the system default locale.

icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ICUResourceBundleTest.java
icu4j/main/tests/translit/src/com/ibm/icu/dev/test/translit/TransliteratorTest.java

index 0b9722209e7423e413fc15c1af054727a19532ab..c2b71632d4b95db2b789d05e36b205e908c5fafd 100644 (file)
@@ -1396,16 +1396,20 @@ public  class ICUResourceBundle extends UResourceBundle {
 
             // fallback to locale ID parent
             if(b == null){
+                OpenType localOpenType = openType;
+                if (openType == OpenType.LOCALE_DEFAULT_ROOT && localeName.equals(defaultID)) {
+                    localOpenType = OpenType.LOCALE_ROOT;
+                }
                 String origLocaleName = (origLocaleID != null) ? origLocaleID : localeName;
                 String fallbackLocaleID = getParentLocaleID(localeName, origLocaleName, openType);
                 if (fallbackLocaleID != null) {
-                    b = instantiateBundle(baseName, fallbackLocaleID, origLocaleName, defaultID, root, openType);
+                    b = instantiateBundle(baseName, fallbackLocaleID, origLocaleName, defaultID, root, localOpenType);
                 }else{
-                    if(openType == OpenType.LOCALE_DEFAULT_ROOT &&
+                    if(localOpenType == OpenType.LOCALE_DEFAULT_ROOT &&
                             !localeIDStartsWithLangSubtag(defaultID, localeName)) {
                         // Go to the default locale before root.
-                        b = instantiateBundle(baseName, defaultID, null, defaultID, root, openType);
-                    } else if(openType != OpenType.LOCALE_ONLY && !rootLocale.isEmpty()) {
+                        b = instantiateBundle(baseName, defaultID, null, defaultID, root, localOpenType);
+                    } else if(localOpenType != OpenType.LOCALE_ONLY && !rootLocale.isEmpty()) {
                         // Ultimately go to root.
                         b = ICUResourceBundle.createBundle(baseName, rootLocale, root);
                     }
index f60869b7cf1087b4cfa9dc11944c28729d50433b..0a8264ec223e0a330687a2ba172d61c5c20def0c 100644 (file)
@@ -1179,4 +1179,20 @@ public final class ICUResourceBundleTest extends TestFmwk {
             assertEquals("Got wrong locale with LOCALE_ROOT", localeRootExpected, localeRootActual);
         }
     }
+
+    @Test
+    public void TestResourceBundleCrash() {
+        final String[] TEST_LOCALE_IDS = new String[] { "nb", "nn", "ht", "hi-Latn" };
+
+        ULocale oldDefaultLocale = ULocale.getDefault();
+        for (String localeID : TEST_LOCALE_IDS) {
+            ULocale locale = ULocale.forLanguageTag(localeID);
+            ULocale.setDefault(locale);
+            UResourceBundle rb = UResourceBundle.getBundleInstance(ICUData.ICU_TRANSLIT_BASE_NAME, locale);
+            assertTrue("Failed to retrieve a resource bundle for " + localeID, rb != null);
+            // the test is to make sure we fell back to root (or otherwise returned SOMETHING)-- all we're really trying to
+            // enrure is that we don't crash with a StackOverflowError when trying to retrieve the bundle
+        }
+        ULocale.setDefault(oldDefaultLocale);
+    }
 }
index bad8781ef248a6994ceaa28b96e855b5c8e56d11..91875fceb37f68b6491d03f7c8e1a48106b0a24f 100644 (file)
@@ -2586,7 +2586,6 @@ public class TransliteratorTest extends TestFmwk {
         }
     }
 
-
     static final String[][] registerRules = {
         {"Any-Dev1", "x > X; y > Y;"},
         {"Any-Dev2", "XY > Z"},