ICU-22149 Be more graceful with missing lang bundle data

See #2635
This commit is contained in:
Shane F. Carr 2023-10-02 05:39:16 +00:00 committed by Markus Scherer
parent e09adbf05a
commit fc386c3a9a
5 changed files with 42 additions and 4 deletions

View file

@ -65,7 +65,8 @@ jobs:
ICU_DATA_FILTER_FILE=../../.ci-builds/data-filter.json ./runConfigureICU Linux && \
make -j2 tests && \
\[ ! -d data/out/build/icudt66l/translit \] && \
(cd test/intltest && LD_LIBRARY_PATH=../../lib:../../tools/ctestfw ./intltest translit/TransliteratorTest/TestBasicTransliteratorEvenWithoutData)
(cd test/intltest && LD_LIBRARY_PATH=../../lib:../../tools/ctestfw ./intltest translit/TransliteratorTest/TestBasicTransliteratorEvenWithoutData) && \
(cd test/cintltst && LANG=C LD_LIBRARY_PATH=../../lib:../../tools/ctestfw ./cintltst /tsutil/cloctst/TestEnglishExemplarCharacters /tsutil/cldrtest/TestCoverage)
displayName: 'Build with Data Filter'
env:
CC: clang

View file

@ -24,7 +24,8 @@
},
"brkitr_dictionaries": {
"blacklist": ["cjdict"]
}
},
"lang_tree": "exclude"
},
"resourceFilters": [
{

View file

@ -68,13 +68,19 @@ ulocdata_open(const char *localeID, UErrorCode *status)
uld->noSubstitute = false;
uld->bundle = ures_open(nullptr, localeID, status);
uld->langBundle = ures_open(U_ICUDATA_LANG, localeID, status);
if (U_FAILURE(*status)) {
uprv_free(uld);
return nullptr;
}
// ICU-22149: not all functions require lang data, so fail gracefully if it is not present
UErrorCode oldStatus = *status;
uld->langBundle = ures_open(U_ICUDATA_LANG, localeID, status);
if (*status == U_MISSING_RESOURCE_ERROR) {
*status = oldStatus;
}
return uld;
}
@ -288,6 +294,11 @@ ulocdata_getLocaleDisplayPattern(ULocaleData *uld,
if (U_FAILURE(*status))
return 0;
if (uld->langBundle == nullptr) {
*status = U_MISSING_RESOURCE_ERROR;
return 0;
}
patternBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", nullptr, &localStatus);
if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
@ -340,6 +351,11 @@ ulocdata_getLocaleSeparator(ULocaleData *uld,
if (U_FAILURE(*status))
return 0;
if (uld->langBundle == nullptr) {
*status = U_MISSING_RESOURCE_ERROR;
return 0;
}
separatorBundle = ures_getByKey(uld->langBundle, "localeDisplayPattern", nullptr, &localStatus);
if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {

View file

@ -1359,6 +1359,14 @@ static void TestCoverage(void){
}
}
// ICU-22149: Cover this code path even if the lang bundle is not present
UErrorCode localStatus = U_ZERO_ERROR;
UChar pattern[20];
ulocdata_getLocaleDisplayPattern(uld, pattern, 20, &localStatus);
if (U_FAILURE(localStatus) && localStatus != U_MISSING_RESOURCE_ERROR) {
log_err("ulocdata_getLocaleDisplayPattern coverage error %s", u_errorName(localStatus));
}
sub = ulocdata_getNoSubstitute(uld);
ulocdata_setNoSubstitute(uld,sub);
ulocdata_close(uld);

View file

@ -31,6 +31,7 @@ public final class LocaleData {
private boolean noSubstitute;
private ICUResourceBundle bundle;
private ICUResourceBundle langBundle;
private MissingResourceException langBundleException;
/**
* EXType for {@link #getExemplarSet(int, int)}.
@ -225,7 +226,12 @@ public final class LocaleData {
public static final LocaleData getInstance(ULocale locale) {
LocaleData ld = new LocaleData();
ld.bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale);
ld.langBundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_LANG_BASE_NAME, locale);
try {
ld.langBundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_LANG_BASE_NAME, locale);
} catch (MissingResourceException mre) {
// Expected error case: ICU-22149
ld.langBundleException = mre;
}
ld.noSubstitute = false;
return ld;
}
@ -421,6 +427,9 @@ public final class LocaleData {
* @stable ICU 4.2
*/
public String getLocaleDisplayPattern() {
if (langBundle == null) {
throw langBundleException;
}
ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN);
String localeDisplayPattern = locDispBundle.getStringWithFallback(PATTERN);
return localeDisplayPattern;
@ -432,6 +441,9 @@ public final class LocaleData {
* @stable ICU 4.2
*/
public String getLocaleSeparator() {
if (langBundle == null) {
throw langBundleException;
}
String sub0 = "{0}";
String sub1 = "{1}";
ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN);