mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-28 23:16:14 +01:00
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. oss-fuzz#16101 Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
parent
5558c668a9
commit
4ddabfc612
@ -1327,9 +1327,7 @@ static GTimeZone *
|
|||||||
parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
|
parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
|
||||||
{
|
{
|
||||||
gint i, tz_length, offset_hours, offset_minutes;
|
gint i, tz_length, offset_hours, offset_minutes;
|
||||||
#ifndef G_DISABLE_ASSERT
|
|
||||||
gint offset_sign = 1;
|
gint offset_sign = 1;
|
||||||
#endif
|
|
||||||
GTimeZone *tz;
|
GTimeZone *tz;
|
||||||
|
|
||||||
/* UTC uses Z suffix */
|
/* UTC uses Z suffix */
|
||||||
@ -1343,9 +1341,7 @@ parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
|
|||||||
for (i = length - 1; i >= 0; i--)
|
for (i = length - 1; i >= 0; i--)
|
||||||
if (text[i] == '+' || text[i] == '-')
|
if (text[i] == '+' || text[i] == '-')
|
||||||
{
|
{
|
||||||
#ifndef G_DISABLE_ASSERT
|
|
||||||
offset_sign = text[i] == '-' ? -1 : 1;
|
offset_sign = text[i] == '-' ? -1 : 1;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
@ -1380,8 +1376,14 @@ parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset)
|
|||||||
tz = g_time_zone_new (text + i);
|
tz = g_time_zone_new (text + i);
|
||||||
|
|
||||||
/* Double-check that the GTimeZone matches our interpretation of the timezone.
|
/* Double-check that the GTimeZone matches our interpretation of the timezone.
|
||||||
* Failure would indicate a bug either here of in the GTimeZone code. */
|
* This can fail because our interpretation is less strict than (for example)
|
||||||
g_assert (g_time_zone_get_offset (tz, 0) == offset_sign * (offset_hours * 3600 + offset_minutes * 60));
|
* 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;
|
return tz;
|
||||||
}
|
}
|
||||||
|
@ -499,6 +499,9 @@ test_GDateTime_new_from_iso8601 (void)
|
|||||||
dt = g_date_time_new_from_iso8601 ("not a date", NULL);
|
dt = g_date_time_new_from_iso8601 ("not a date", NULL);
|
||||||
g_assert_null (dt);
|
g_assert_null (dt);
|
||||||
|
|
||||||
|
dt = g_date_time_new_from_iso8601 (" +55", NULL);
|
||||||
|
g_assert_null (dt);
|
||||||
|
|
||||||
/* Check common case */
|
/* Check common case */
|
||||||
dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42Z", NULL);
|
dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42Z", NULL);
|
||||||
ASSERT_DATE (dt, 2016, 8, 24);
|
ASSERT_DATE (dt, 2016, 8, 24);
|
||||||
|
Loading…
Reference in New Issue
Block a user