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 colons;
|
||||
gchar *tmp;
|
||||
gsize tmp_len;
|
||||
gunichar c;
|
||||
gboolean alt_digits = FALSE;
|
||||
gboolean pad_set = FALSE;
|
||||
gchar *pad = "";
|
||||
gchar *ampm;
|
||||
const gchar *name;
|
||||
const gchar *tz;
|
||||
|
||||
while (*format)
|
||||
@ -2257,10 +2259,10 @@ g_date_time_format_locale (GDateTime *datetime,
|
||||
g_string_append_len (outstr, format, len);
|
||||
else
|
||||
{
|
||||
tmp = g_locale_from_utf8 (format, len, NULL, NULL, NULL);
|
||||
tmp = g_locale_from_utf8 (format, len, NULL, &tmp_len, NULL);
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
g_string_append (outstr, tmp);
|
||||
g_string_append_len (outstr, tmp, tmp_len);
|
||||
g_free (tmp);
|
||||
}
|
||||
}
|
||||
@ -2284,16 +2286,72 @@ g_date_time_format_locale (GDateTime *datetime,
|
||||
switch (c)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
case 'c':
|
||||
{
|
||||
@ -2329,7 +2387,21 @@ g_date_time_format_locale (GDateTime *datetime,
|
||||
g_date_time_get_week_numbering_year (datetime));
|
||||
break;
|
||||
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;
|
||||
case 'H':
|
||||
format_number (outstr, alt_digits, pad_set ? pad : "0", 2,
|
||||
@ -2367,44 +2439,56 @@ g_date_time_format_locale (GDateTime *datetime,
|
||||
goto next_mod;
|
||||
case 'p':
|
||||
ampm = (gchar *) GET_AMPM (datetime);
|
||||
#if defined (HAVE_LANGINFO_TIME)
|
||||
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);
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
ampm = g_utf8_strup (ampm, -1);
|
||||
tmp_len = strlen (ampm);
|
||||
if (!locale_is_utf8)
|
||||
{
|
||||
#if defined (HAVE_LANGINFO_TIME)
|
||||
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);
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
ampm = tmp;
|
||||
}
|
||||
g_string_append (outstr, ampm);
|
||||
g_string_append_len (outstr, ampm, tmp_len);
|
||||
g_free (ampm);
|
||||
break;
|
||||
case 'P':
|
||||
ampm = (gchar *) GET_AMPM (datetime);
|
||||
#if defined (HAVE_LANGINFO_TIME)
|
||||
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);
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
ampm = g_utf8_strdown (ampm, -1);
|
||||
tmp_len = strlen (ampm);
|
||||
if (!locale_is_utf8)
|
||||
{
|
||||
#if defined (HAVE_LANGINFO_TIME)
|
||||
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);
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
ampm = tmp;
|
||||
}
|
||||
g_string_append (outstr, ampm);
|
||||
g_string_append_len (outstr, ampm, tmp_len);
|
||||
g_free (ampm);
|
||||
break;
|
||||
case 'r':
|
||||
@ -2482,13 +2566,14 @@ g_date_time_format_locale (GDateTime *datetime,
|
||||
break;
|
||||
case 'Z':
|
||||
tz = g_date_time_get_timezone_abbreviation (datetime);
|
||||
tmp_len = strlen (tz);
|
||||
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)
|
||||
return FALSE;
|
||||
}
|
||||
g_string_append (outstr, tz);
|
||||
g_string_append_len (outstr, tz, tmp_len);
|
||||
if (!locale_is_utf8)
|
||||
g_free (tmp);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user