summaryrefslogtreecommitdiff
path: root/src/bin/initdb/initdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/initdb/initdb.c')
-rw-r--r--src/bin/initdb/initdb.c58
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");