summaryrefslogtreecommitdiff
path: root/icu4j/main/classes
diff options
context:
space:
mode:
authorVictor Chang <vichang@google.com>2018-05-21 17:51:11 +0100
committerVictor Chang <vichang@google.com>2018-05-25 10:35:03 +0100
commit5a0b0d722c203bcffc922b580bf64780de0eed66 (patch)
tree98a902c37e002b0054fd8b03e7ac19056f3a92af /icu4j/main/classes
parent38f23dcbf8eecc5312de4cdaf0da2dac34b08969 (diff)
downloadicu-5a0b0d722c203bcffc922b580bf64780de0eed66.tar.gz
Android Patch: Fix BCP 47 locale extension in ULocale for first usage
Upstream ticket: http://bugs.icu-project.org/trac/ticket/13776 - For the first usage of locale extension, there is interdependency between ULocale and KeyTypeData. The example call stack would be: ULocale.forLocale -> KeyTypeData.toLegacyKey -> KeyTypeData.<clinit> -> ULocale.getDefault -> ULocale.forLocale -> KeyTypeData.toLegacyKey. - Break the inter-dependency by not using ULocale.getDefault for fallback icu4c/source/data/misc/keyTypeData.txt indicates "no fallback" in the resource bundle. ========================== keyTypeData:table(nofallback) ICUResourceBundle#instantiateBundle doesn't seem to use the value of ULocale.getDefault foe loading the resource if the resource bundle has no fallback. ======= ICUResourceBundle#instantiateBundle ======= if (openType == OpenType.DIRECT || (b != null && b.getNoFallback())) { return b; } ---- <use default locale> ---- ================================================== Before going into instantiateBundle(), if the caller didn't request disableFallback or OpenType.DIRECT, the code calls ULocale.getDefault(). If the caller did, then a null String is used for the defaultID. ================================================= public static ICUResourceBundle getBundleInstance(String baseName, String localeID, ClassLoader root, OpenType openType) { if (baseName == null) { baseName = ICUData.ICU_BASE_NAME; } localeID = ULocale.getBaseName(localeID); ICUResourceBundle b; if (openType == OpenType.LOCALE_DEFAULT_ROOT) { b = instantiateBundle(baseName, localeID, ULocale.getDefault().getBaseName(), root, openType); } else { b = instantiateBundle(baseName, localeID, null, root, openType); } if(b==null){ throw new MissingResourceException( "Could not find the bundle "+ baseName+"/"+ localeID+".res","",""); } return b; } ================================================ I verified that the bundle object's noFallback field is true for this data file. - Add a test that will fail individually when the bug occurs. I don't know how to de-initalize class KeyTypeData during the test, but we could potentially put the test into a separate test suite. Other codes in many places, e.g. JUnit, Zygote, framework, could still hide the bug by initializing KeyTypeMap and being the first victim of the bug. Bug: 70943715 Test: cts-tradefed run cts-dev -m CtsIcuTestCases -t android.icu.dev.test.util.ULocaleTest#TestForLanguageTagBug13776 pass after the CL. previously, it will fail if running individually. Test: cts-tradefed run cts-dev -m CtsIcuTestCases Test: cts-tradefed run cts-dev -m CtsLibcoreTestCases Test: ant check Change-Id: I50654a262777426c984023354797c91efaef9baf
Diffstat (limited to 'icu4j/main/classes')
-rw-r--r--icu4j/main/classes/core/src/com/ibm/icu/impl/locale/KeyTypeData.java8
1 files changed, 8 insertions, 0 deletions
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/KeyTypeData.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/KeyTypeData.java
index a8dda07af..776d0f0c0 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/KeyTypeData.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/KeyTypeData.java
@@ -210,10 +210,18 @@ public class KeyTypeData {
}
private static void initFromResourceBundle() {
+ // Android patch: Avoid inter-dependency issue on ULocale.getDefault(). Ticket#13776
+ /*
UResourceBundle keyTypeDataRes = UResourceBundle.getBundleInstance(
ICUData.ICU_BASE_NAME,
"keyTypeData",
ICUResourceBundle.ICU_DATA_CLASS_LOADER);
+ */
+ UResourceBundle keyTypeDataRes = ICUResourceBundle.getBundleInstance(
+ ICUData.ICU_BASE_NAME,
+ "keyTypeData",
+ ICUResourceBundle.ICU_DATA_CLASS_LOADER,
+ ICUResourceBundle.OpenType.DIRECT);
getKeyInfo(keyTypeDataRes.get("keyInfo"));
getTypeInfo(keyTypeDataRes.get("typeInfo"));