[glib] g_date_time_format_locale: ensure locale encoding is used
- From: Руслан Ижбулатов <ruslanizhb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] g_date_time_format_locale: ensure locale encoding is used
- Date: Mon, 16 May 2016 05:19:40 +0000 (UTC)
commit 6a1e8e8fa70fdd734b79ae3b5e2bf9ab64a31c90
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date: Sat May 7 17:02:55 2016 +0000
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
glib/gdatetime.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 98 insertions(+), 13 deletions(-)
---
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index ebc4837..8ff0223 100644
--- a/glib/gdatetime.c
+++ b/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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]