ICU-22249 Fixed endless loop in ICUResourceBundle when you ask for a locale with a nonstandard parent and that locale

is also the system default locale.
This commit is contained in:
Rich Gillam 2023-01-27 18:04:35 -08:00 committed by Rich Gillam
parent 3f05361b41
commit 08f14db4c4
3 changed files with 24 additions and 5 deletions

View 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);
}

View 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);
}
}

View file

@ -2586,7 +2586,6 @@ public class TransliteratorTest extends TestFmwk {
}
}
static final String[][] registerRules = {
{"Any-Dev1", "x > X; y > Y;"},
{"Any-Dev2", "XY > Z"},