mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-02 07:36:17 +01:00
g_date_time_format_locale: ensure locale encoding is used
Fallback code for g_date_time_format_locale() fetches translated strings (such as day and month names) from .mo catalogues via gettext. These strings always come in UTF-8 encoding, because that is the encoding that glib sets when it initializes gettext for itself. However, the non-fallback code uses nl_langinfo() and expects its results to be in locale-dependent encoding. This mismatch can result in UTF-8 strings being converted to UTF-8, producing gibberish. Fix this by converting UTF-8 strings to locale-dependent encoding before using them. Also fix the code that was already doing the locale->UTF-8 conversion to not convert the strings when they are already UTF-8-encoded. https://bugzilla.gnome.org/show_bug.cgi?id=766092
This commit is contained in:
parent
6055954a09
commit
6a1e8e8fa7
111
glib/gdatetime.c
111
glib/gdatetime.c
@ -2241,11 +2241,13 @@ g_date_time_format_locale (GDateTime *datetime,
|
|||||||
guint len;
|
guint len;
|
||||||
guint colons;
|
guint colons;
|
||||||
gchar *tmp;
|
gchar *tmp;
|
||||||
|
gsize tmp_len;
|
||||||
gunichar c;
|
gunichar c;
|
||||||
gboolean alt_digits = FALSE;
|
gboolean alt_digits = FALSE;
|
||||||
gboolean pad_set = FALSE;
|
gboolean pad_set = FALSE;
|
||||||
gchar *pad = "";
|
gchar *pad = "";
|
||||||
gchar *ampm;
|
gchar *ampm;
|
||||||
|
const gchar *name;
|
||||||
const gchar *tz;
|
const gchar *tz;
|
||||||
|
|
||||||
while (*format)
|
while (*format)
|
||||||
@ -2257,10 +2259,10 @@ g_date_time_format_locale (GDateTime *datetime,
|
|||||||
g_string_append_len (outstr, format, len);
|
g_string_append_len (outstr, format, len);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp = g_locale_from_utf8 (format, len, NULL, NULL, NULL);
|
tmp = g_locale_from_utf8 (format, len, NULL, &tmp_len, NULL);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
g_string_append (outstr, tmp);
|
g_string_append_len (outstr, tmp, tmp_len);
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2284,16 +2286,72 @@ g_date_time_format_locale (GDateTime *datetime,
|
|||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
g_string_append (outstr, WEEKDAY_ABBR (datetime));
|
name = WEEKDAY_ABBR (datetime);
|
||||||
|
#if !defined (HAVE_LANGINFO_TIME)
|
||||||
|
if (!locale_is_utf8)
|
||||||
|
{
|
||||||
|
tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
g_string_append_len (outstr, tmp, tmp_len);
|
||||||
|
g_free (tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
g_string_append (outstr, name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
g_string_append (outstr, WEEKDAY_FULL (datetime));
|
name = WEEKDAY_FULL (datetime);
|
||||||
|
#if !defined (HAVE_LANGINFO_TIME)
|
||||||
|
if (!locale_is_utf8)
|
||||||
|
{
|
||||||
|
tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
g_string_append_len (outstr, tmp, tmp_len);
|
||||||
|
g_free (tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
g_string_append (outstr, name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
g_string_append (outstr, MONTH_ABBR (datetime));
|
name = MONTH_ABBR (datetime);
|
||||||
|
#if !defined (HAVE_LANGINFO_TIME)
|
||||||
|
if (!locale_is_utf8)
|
||||||
|
{
|
||||||
|
tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
g_string_append_len (outstr, tmp, tmp_len);
|
||||||
|
g_free (tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
g_string_append (outstr, name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
g_string_append (outstr, MONTH_FULL (datetime));
|
name = MONTH_FULL (datetime);
|
||||||
|
#if !defined (HAVE_LANGINFO_TIME)
|
||||||
|
if (!locale_is_utf8)
|
||||||
|
{
|
||||||
|
tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
g_string_append_len (outstr, tmp, tmp_len);
|
||||||
|
g_free (tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
g_string_append (outstr, name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
{
|
{
|
||||||
@ -2329,7 +2387,21 @@ g_date_time_format_locale (GDateTime *datetime,
|
|||||||
g_date_time_get_week_numbering_year (datetime));
|
g_date_time_get_week_numbering_year (datetime));
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
g_string_append (outstr, MONTH_ABBR (datetime));
|
name = MONTH_ABBR (datetime);
|
||||||
|
#if !defined (HAVE_LANGINFO_TIME)
|
||||||
|
if (!locale_is_utf8)
|
||||||
|
{
|
||||||
|
tmp = g_locale_from_utf8 (name, -1, NULL, &tmp_len, NULL);
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
g_string_append_len (outstr, tmp, tmp_len);
|
||||||
|
g_free (tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
g_string_append (outstr, name);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
format_number (outstr, alt_digits, pad_set ? pad : "0", 2,
|
format_number (outstr, alt_digits, pad_set ? pad : "0", 2,
|
||||||
@ -2367,44 +2439,56 @@ g_date_time_format_locale (GDateTime *datetime,
|
|||||||
goto next_mod;
|
goto next_mod;
|
||||||
case 'p':
|
case 'p':
|
||||||
ampm = (gchar *) GET_AMPM (datetime);
|
ampm = (gchar *) GET_AMPM (datetime);
|
||||||
|
#if defined (HAVE_LANGINFO_TIME)
|
||||||
if (!locale_is_utf8)
|
if (!locale_is_utf8)
|
||||||
{
|
{
|
||||||
|
/* This assumes that locale encoding can't have embedded NULs */
|
||||||
ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL);
|
ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
ampm = g_utf8_strup (ampm, -1);
|
ampm = g_utf8_strup (ampm, -1);
|
||||||
|
tmp_len = strlen (ampm);
|
||||||
if (!locale_is_utf8)
|
if (!locale_is_utf8)
|
||||||
{
|
{
|
||||||
|
#if defined (HAVE_LANGINFO_TIME)
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
tmp = g_locale_from_utf8 (ampm, -1, NULL, NULL, NULL);
|
#endif
|
||||||
|
tmp = g_locale_from_utf8 (ampm, -1, NULL, &tmp_len, NULL);
|
||||||
g_free (ampm);
|
g_free (ampm);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ampm = tmp;
|
ampm = tmp;
|
||||||
}
|
}
|
||||||
g_string_append (outstr, ampm);
|
g_string_append_len (outstr, ampm, tmp_len);
|
||||||
g_free (ampm);
|
g_free (ampm);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
ampm = (gchar *) GET_AMPM (datetime);
|
ampm = (gchar *) GET_AMPM (datetime);
|
||||||
|
#if defined (HAVE_LANGINFO_TIME)
|
||||||
if (!locale_is_utf8)
|
if (!locale_is_utf8)
|
||||||
{
|
{
|
||||||
|
/* This assumes that locale encoding can't have embedded NULs */
|
||||||
ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL);
|
ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
ampm = g_utf8_strdown (ampm, -1);
|
ampm = g_utf8_strdown (ampm, -1);
|
||||||
|
tmp_len = strlen (ampm);
|
||||||
if (!locale_is_utf8)
|
if (!locale_is_utf8)
|
||||||
{
|
{
|
||||||
|
#if defined (HAVE_LANGINFO_TIME)
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
tmp = g_locale_from_utf8 (ampm, -1, NULL, NULL, NULL);
|
#endif
|
||||||
|
tmp = g_locale_from_utf8 (ampm, -1, NULL, &tmp_len, NULL);
|
||||||
g_free (ampm);
|
g_free (ampm);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ampm = tmp;
|
ampm = tmp;
|
||||||
}
|
}
|
||||||
g_string_append (outstr, ampm);
|
g_string_append_len (outstr, ampm, tmp_len);
|
||||||
g_free (ampm);
|
g_free (ampm);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -2482,13 +2566,14 @@ g_date_time_format_locale (GDateTime *datetime,
|
|||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
tz = g_date_time_get_timezone_abbreviation (datetime);
|
tz = g_date_time_get_timezone_abbreviation (datetime);
|
||||||
|
tmp_len = strlen (tz);
|
||||||
if (!locale_is_utf8)
|
if (!locale_is_utf8)
|
||||||
{
|
{
|
||||||
tz = tmp = g_locale_from_utf8 (tz, -1, NULL, NULL, NULL);
|
tz = tmp = g_locale_from_utf8 (tz, -1, NULL, &tmp_len, NULL);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
g_string_append (outstr, tz);
|
g_string_append_len (outstr, tz, tmp_len);
|
||||||
if (!locale_is_utf8)
|
if (!locale_is_utf8)
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user