diff options
Diffstat (limited to 'src/bin/initdb/initdb.c')
-rw-r--r-- | src/bin/initdb/initdb.c | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 6b20a962ecc..d5ac25904da 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -2243,6 +2243,58 @@ check_icu_locale_encoding(int user_enc) } /* + * Perform best-effort check that the locale is a valid one. Should be + * consistent with pg_locale.c, except that it doesn't need to open the + * collator (that will happen during post-bootstrap initialization). + */ +static void +icu_validate_locale(const char *loc_str) +{ +#ifdef USE_ICU + UErrorCode status; + char lang[ULOC_LANG_CAPACITY]; + bool found = false; + + /* validate that we can extract the language */ + status = U_ZERO_ERROR; + uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status); + if (U_FAILURE(status)) + { + pg_fatal("could not get language from locale \"%s\": %s", + loc_str, u_errorName(status)); + return; + } + + /* check for special language name */ + if (strcmp(lang, "") == 0 || + strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0 || + strcmp(lang, "c") == 0 || strcmp(lang, "posix") == 0) + found = true; + + /* search for matching language within ICU */ + for (int32_t i = 0; !found && i < uloc_countAvailable(); i++) + { + const char *otherloc = uloc_getAvailable(i); + char otherlang[ULOC_LANG_CAPACITY]; + + status = U_ZERO_ERROR; + uloc_getLanguage(otherloc, otherlang, ULOC_LANG_CAPACITY, &status); + if (U_FAILURE(status)) + continue; + + if (strcmp(lang, otherlang) == 0) + found = true; + } + + if (!found) + pg_fatal("locale \"%s\" has unknown language \"%s\"", + loc_str, lang); +#else + pg_fatal("ICU is not supported in this build"); +#endif +} + +/* * Determine default ICU locale by opening the default collator and reading * its locale. * @@ -2344,9 +2396,11 @@ setlocales(void) printf(_("Using default ICU locale \"%s\".\n"), icu_locale); } + icu_validate_locale(icu_locale); + /* - * In supported builds, the ICU locale ID will be checked by the - * backend during post-bootstrap initialization. + * In supported builds, the ICU locale ID will be opened during + * post-bootstrap initialization, which will perform extra checks. */ #ifndef USE_ICU pg_fatal("ICU is not supported in this build"); |