[glib/glib-2-60: 1/2] gdatetime: Avoid an assertion failure when parsing some ISO 8601 dates



commit 2ce0d7ab7c9ce5fab435008cf9637cadf07406fe
Author: Philip Withnall <withnall endlessm com>
Date:   Tue Jul 30 14:37:48 2019 +0100

    gdatetime: Avoid an assertion failure when parsing some ISO 8601 dates
    
    Some malformed ISO 8601 date/time strings were causing an assertion
    failure when passed to `g_date_time_new_from_iso8601()`, due to a
    mismatch between the bounds checking of timezone offsets in `GDateTime`
    and `GTimeZone`. Fix that and add a unit test for it.
    
    (Trivial backport of !1017.)
    
    oss-fuzz#16101
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 glib/gdatetime.c       | 10 ++++++++--
 glib/tests/gdatetime.c |  3 +++
 2 files changed, 11 insertions(+), 2 deletions(-)
---
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index 8abf45a87..7c94adf56 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -1353,8 +1353,14 @@ parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
   tz = g_time_zone_new (text + i);
 
   /* Double-check that the GTimeZone matches our interpretation of the timezone.
-   * Failure would indicate a bug either here of in the GTimeZone code. */
-  g_assert (g_time_zone_get_offset (tz, 0) == offset_sign * (offset_hours * 3600 + offset_minutes * 60));
+   * This can fail because our interpretation is less strict than (for example)
+   * parse_time() in gtimezone.c, which restricts the range of the parsed
+   * integers. */
+  if (g_time_zone_get_offset (tz, 0) != offset_sign * (offset_hours * 3600 + offset_minutes * 60))
+    {
+      g_time_zone_unref (tz);
+      return NULL;
+    }
 
   return tz;
 }
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index 00e22181e..8178e2205 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -490,6 +490,9 @@ test_GDateTime_new_from_iso8601 (void)
   dt = g_date_time_new_from_iso8601 ("not a date", NULL);
   g_assert_null (dt);
 
+  dt = g_date_time_new_from_iso8601 (" +55", NULL);
+  g_assert_null (dt);
+
   /* Check common case */
   dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42Z", NULL);
   ASSERT_DATE (dt, 2016, 8, 24);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]