mirror of
https://github.com/flatpak/flatpak.git
synced 2026-01-26 14:13:26 +00:00
config: Rework handling of extra-languages to change locale format
Accept the locale format as documented by `setlocale(3)`, rather than another arbitrary format. This reworks the validation code, and was tested to accept all the locales on my F30 system using: ``` flatpak config --user --set extra-languages $(locale -a | tr -s '\n' ';' | head -c -1) ``` Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
parent
a3a7f3214c
commit
cc7474d0e9
@ -68,49 +68,73 @@ looks_like_a_language (const char *s)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
looks_like_a_region (const char *s)
|
||||
looks_like_a_territory (const char *s)
|
||||
{
|
||||
g_auto(GStrv) locale = g_strsplit (s, "_", 3);
|
||||
int i;
|
||||
int len;
|
||||
gsize len = strlen (s);
|
||||
gsize i;
|
||||
|
||||
if (!looks_like_a_language(locale[0]))
|
||||
if (len < 2)
|
||||
return FALSE;
|
||||
|
||||
if (locale[1] != NULL)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
len = strlen (locale[1]);
|
||||
|
||||
// This can be either GB or Latn
|
||||
if (len < 2 || len > 4)
|
||||
if (!g_ascii_isalpha (s[i]) || !g_ascii_isupper (s[i]))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if ((locale[2] == NULL) && (!g_ascii_isalpha (locale[1][i]) || !g_ascii_isupper (locale[1][i])))
|
||||
return FALSE;
|
||||
else if (!g_ascii_isalpha (locale[1][i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_strv_length (locale) > 2)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
looks_like_a_codeset_or_modifier (const char *s)
|
||||
{
|
||||
gsize len = strlen (s);
|
||||
gsize i;
|
||||
|
||||
if (len < 1)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
len = strlen (locale[2]);
|
||||
|
||||
if (len < 2 || len > 3)
|
||||
if (!g_ascii_isalnum (s[i]) && s[i] != '-')
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!g_ascii_isalpha (locale[2][i]) || !g_ascii_isupper (locale[2][i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
looks_like_a_locale (const char *s)
|
||||
{
|
||||
g_autofree gchar *locale = g_strdup (s);
|
||||
gchar *language, *territory, *codeset, *modifier;
|
||||
|
||||
modifier = strchr (locale, '@');
|
||||
if (modifier != NULL)
|
||||
*modifier++ = '\0';
|
||||
|
||||
codeset = strchr (locale, '.');
|
||||
if (codeset != NULL)
|
||||
*codeset++ = '\0';
|
||||
|
||||
territory = strchr (locale, '_');
|
||||
if (territory != NULL)
|
||||
*territory++ = '\0';
|
||||
|
||||
language = locale;
|
||||
|
||||
if (!looks_like_a_language (language))
|
||||
return FALSE;
|
||||
if (territory != NULL && !looks_like_a_territory (territory))
|
||||
return FALSE;
|
||||
if (codeset != NULL && !looks_like_a_codeset_or_modifier (codeset))
|
||||
return FALSE;
|
||||
if (modifier != NULL && !looks_like_a_codeset_or_modifier (modifier))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_locale (const char *value, GError **error)
|
||||
{
|
||||
@ -120,7 +144,7 @@ parse_locale (const char *value, GError **error)
|
||||
strs = g_strsplit (value, ";", 0);
|
||||
for (i = 0; strs[i]; i++)
|
||||
{
|
||||
if (!looks_like_a_language (strs[i]) && !looks_like_a_region (strs[i]))
|
||||
if (!looks_like_a_language (strs[i]) && !looks_like_a_locale (strs[i]))
|
||||
{
|
||||
flatpak_fail (error, _("'%s' does not look like a language/locale code"), strs[i]);
|
||||
return NULL;
|
||||
|
||||
@ -14607,9 +14607,10 @@ flatpak_dir_get_default_locale_languages (FlatpakDir *self)
|
||||
extra_languages = flatpak_dir_get_config_strv (self, "xa.extra-languages");
|
||||
for (i = 0; extra_languages != NULL && extra_languages[i] != NULL; i++)
|
||||
{
|
||||
g_auto(GStrv) locales = g_strsplit (extra_languages[i], "_", -1);
|
||||
g_free (extra_languages[i]);
|
||||
extra_languages[i] = g_strdup (locales[0]);
|
||||
/* Strip the locale, modifier or codeset, if present. */
|
||||
gchar *match = strpbrk (extra_languages[i], "._@");
|
||||
if (match != NULL)
|
||||
*match = '\0';
|
||||
}
|
||||
|
||||
if (flatpak_dir_is_user (self))
|
||||
|
||||
@ -1687,12 +1687,15 @@ flatpak_installation_get_default_languages (FlatpakInstallation *self,
|
||||
* @self: a #FlatpakInstallation
|
||||
* @error: return location for a #GError
|
||||
*
|
||||
* Like flatpak_installation_get_default_languages() but includes region
|
||||
* information (e.g. en_US rather than en) which may be included in the
|
||||
* xa.extra-languages configuration.
|
||||
* Like flatpak_installation_get_default_languages() but includes territory
|
||||
* information (e.g. `en_US` rather than `en`) which may be included in the
|
||||
* `xa.extra-languages` configuration.
|
||||
*
|
||||
* Strings returned by this function are in the format specified by
|
||||
* [`setlocale()`](man:setlocale): `language[_territory][.codeset][@modifier]`.
|
||||
*
|
||||
* Returns: (array zero-terminated=1) (element-type utf8) (transfer full):
|
||||
* A possibly empty array of language and locale strings, or %NULL on error.
|
||||
* A possibly empty array of locale strings, or %NULL on error.
|
||||
* Since: 1.5.1
|
||||
*/
|
||||
char **
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user