[glib] gdatetime: Fix handling of unsupported nl_langinfo() items
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gdatetime: Fix handling of unsupported nl_langinfo() items
- Date: Tue, 28 Nov 2017 14:26:37 +0000 (UTC)
commit bccc1057e33277fd566d51166a30e8d1e17c20e0
Author: Philip Withnall <withnall endlessm com>
Date: Thu Nov 16 09:30:32 2017 +0000
gdatetime: Fix handling of unsupported nl_langinfo() items
If nl_langinfo() doesn’t support a particular item, it returns the empty
string. We should check for that and return NULL from
g_date_time_format() accordingly, otherwise the user could unwittingly
end up with a formatted date/time which is missing some or all of its
components.
This arose with %r in de_DE, which is unsupported by nl_langinfo()
because Germans almost never write time in 12-hour format.
Add a unit test.
Signed-off-by: Philip Withnall <withnall endlessm com>
https://bugzilla.gnome.org/show_bug.cgi?id=790416
glib/gdatetime.c | 21 ++++++++++++++++++++-
glib/tests/gdatetime.c | 22 ++++++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletions(-)
---
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index 045c578..5123c20 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -2695,6 +2695,8 @@ g_date_time_format_locale (GDateTime *datetime,
{
case 'a':
name = WEEKDAY_ABBR (datetime);
+ if (g_strcmp0 (name, "") == 0)
+ return FALSE;
#if !defined (HAVE_LANGINFO_TIME)
if (!locale_is_utf8)
{
@@ -2712,6 +2714,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'A':
name = WEEKDAY_FULL (datetime);
+ if (g_strcmp0 (name, "") == 0)
+ return FALSE;
#if !defined (HAVE_LANGINFO_TIME)
if (!locale_is_utf8)
{
@@ -2729,6 +2733,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'b':
name = MONTH_ABBR (datetime);
+ if (g_strcmp0 (name, "") == 0)
+ return FALSE;
#if !defined (HAVE_LANGINFO_TIME)
if (!locale_is_utf8)
{
@@ -2746,6 +2752,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'B':
name = MONTH_FULL (datetime);
+ if (g_strcmp0 (name, "") == 0)
+ return FALSE;
#if !defined (HAVE_LANGINFO_TIME)
if (!locale_is_utf8)
{
@@ -2763,6 +2771,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'c':
{
+ if (g_strcmp0 (PREFERRED_DATE_TIME_FMT, "") == 0)
+ return FALSE;
if (!g_date_time_locale_format_locale (datetime, PREFERRED_DATE_TIME_FMT,
outstr, locale_is_utf8))
return FALSE;
@@ -2796,6 +2806,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'h':
name = MONTH_ABBR (datetime);
+ if (g_strcmp0 (name, "") == 0)
+ return FALSE;
#if !defined (HAVE_LANGINFO_TIME)
if (!locale_is_utf8)
{
@@ -2855,6 +2867,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'r':
{
+ if (g_strcmp0 (PREFERRED_12HR_TIME_FMT, "") == 0)
+ return FALSE;
if (!g_date_time_locale_format_locale (datetime, PREFERRED_12HR_TIME_FMT,
outstr, locale_is_utf8))
return FALSE;
@@ -2895,6 +2909,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'x':
{
+ if (g_strcmp0 (PREFERRED_DATE_FMT, "") == 0)
+ return FALSE;
if (!g_date_time_locale_format_locale (datetime, PREFERRED_DATE_FMT,
outstr, locale_is_utf8))
return FALSE;
@@ -2902,6 +2918,8 @@ g_date_time_format_locale (GDateTime *datetime,
break;
case 'X':
{
+ if (g_strcmp0 (PREFERRED_TIME_FMT, "") == 0)
+ return FALSE;
if (!g_date_time_locale_format_locale (datetime, PREFERRED_TIME_FMT,
outstr, locale_is_utf8))
return FALSE;
@@ -3059,7 +3077,8 @@ g_date_time_format_locale (GDateTime *datetime,
* for the specifier.
*
* Returns: a newly allocated string formatted to the requested format
- * or %NULL in the case that there was an error. The string
+ * or %NULL in the case that there was an error (such as a format specifier
+ * not being supported in the current locale). The string
* should be freed with g_free().
*
* Since: 2.26
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index fc117e2..296a1e9 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -1818,6 +1818,27 @@ test_strftime (void)
}
#pragma GCC diagnostic pop
+/* Check that g_date_time_format() correctly returns %NULL for format
+ * placeholders which are not supported in the current locale. */
+static void
+test_GDateTime_strftime_error_handling (void)
+{
+ gchar *oldlocale;
+
+ oldlocale = g_strdup (setlocale (LC_ALL, NULL));
+ setlocale (LC_ALL, "de_DE.utf-8");
+ if (strstr (setlocale (LC_ALL, NULL), "de_DE") != NULL)
+ {
+ /* de_DE doesn’t ever write time in 12-hour notation, so %r is
+ * unsupported for it. */
+ TEST_PRINTF_TIME (23, 0, 0, "%r", NULL);
+ }
+ else
+ g_test_skip ("locale de_DE not available, skipping error handling tests");
+ setlocale (LC_ALL, oldlocale);
+ g_free (oldlocale);
+}
+
static void
test_find_interval (void)
{
@@ -2141,6 +2162,7 @@ main (gint argc,
g_test_add_func ("/GDateTime/printf", test_GDateTime_printf);
g_test_add_func ("/GDateTime/non_utf8_printf", test_non_utf8_printf);
g_test_add_func ("/GDateTime/strftime", test_strftime);
+ g_test_add_func ("/GDateTime/strftime/error_handling", test_GDateTime_strftime_error_handling);
g_test_add_func ("/GDateTime/modifiers", test_modifiers);
g_test_add_func ("/GDateTime/to_local", test_GDateTime_to_local);
g_test_add_func ("/GDateTime/to_unix", test_GDateTime_to_unix);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]