mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 18:26:19 +01:00
Merge branch 'ossfuzz-9673-bookmark-date-overflow' into 'master'
gtimer: Add overflow checks to g_time_val_from_iso8601() See merge request GNOME/glib!225
This commit is contained in:
commit
7458defa9a
@ -345,6 +345,8 @@ mktime_utc (struct tm *tm)
|
||||
* zone indicator. (In the absence of any time zone indication, the
|
||||
* timestamp is assumed to be in local time.)
|
||||
*
|
||||
* Any leading or trailing space in @iso_date is ignored.
|
||||
*
|
||||
* Returns: %TRUE if the conversion was successful.
|
||||
*
|
||||
* Since: 2.12
|
||||
@ -355,6 +357,8 @@ g_time_val_from_iso8601 (const gchar *iso_date,
|
||||
{
|
||||
struct tm tm = {0};
|
||||
long val;
|
||||
long mday, mon, year;
|
||||
long hour, min, sec;
|
||||
|
||||
g_return_val_if_fail (iso_date != NULL, FALSE);
|
||||
g_return_val_if_fail (time_ != NULL, FALSE);
|
||||
@ -368,30 +372,42 @@ g_time_val_from_iso8601 (const gchar *iso_date,
|
||||
if (*iso_date == '\0')
|
||||
return FALSE;
|
||||
|
||||
if (!g_ascii_isdigit (*iso_date) && *iso_date != '-' && *iso_date != '+')
|
||||
if (!g_ascii_isdigit (*iso_date) && *iso_date != '+')
|
||||
return FALSE;
|
||||
|
||||
val = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
if (*iso_date == '-')
|
||||
{
|
||||
/* YYYY-MM-DD */
|
||||
tm.tm_year = val - 1900;
|
||||
year = val;
|
||||
iso_date++;
|
||||
tm.tm_mon = strtoul (iso_date, (char **)&iso_date, 10) - 1;
|
||||
|
||||
|
||||
mon = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
if (*iso_date++ != '-')
|
||||
return FALSE;
|
||||
|
||||
tm.tm_mday = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
mday = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* YYYYMMDD */
|
||||
tm.tm_mday = val % 100;
|
||||
tm.tm_mon = (val % 10000) / 100 - 1;
|
||||
tm.tm_year = val / 10000 - 1900;
|
||||
mday = val % 100;
|
||||
mon = (val % 10000) / 100;
|
||||
year = val / 10000;
|
||||
}
|
||||
|
||||
/* Validation. */
|
||||
if (year < 1900 || year > G_MAXINT)
|
||||
return FALSE;
|
||||
if (mon < 1 || mon > 12)
|
||||
return FALSE;
|
||||
if (mday < 1 || mday > 31)
|
||||
return FALSE;
|
||||
|
||||
tm.tm_mday = mday;
|
||||
tm.tm_mon = mon - 1;
|
||||
tm.tm_year = year - 1900;
|
||||
|
||||
if (*iso_date != 'T')
|
||||
return FALSE;
|
||||
|
||||
@ -405,34 +421,50 @@ g_time_val_from_iso8601 (const gchar *iso_date,
|
||||
if (*iso_date == ':')
|
||||
{
|
||||
/* hh:mm:ss */
|
||||
tm.tm_hour = val;
|
||||
hour = val;
|
||||
iso_date++;
|
||||
tm.tm_min = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
min = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
|
||||
if (*iso_date++ != ':')
|
||||
return FALSE;
|
||||
|
||||
tm.tm_sec = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
sec = strtoul (iso_date, (char **)&iso_date, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* hhmmss */
|
||||
tm.tm_sec = val % 100;
|
||||
tm.tm_min = (val % 10000) / 100;
|
||||
tm.tm_hour = val / 10000;
|
||||
sec = val % 100;
|
||||
min = (val % 10000) / 100;
|
||||
hour = val / 10000;
|
||||
}
|
||||
|
||||
/* Validation. Allow up to 2 leap seconds when validating @sec. */
|
||||
if (hour > 23)
|
||||
return FALSE;
|
||||
if (min > 59)
|
||||
return FALSE;
|
||||
if (sec > 61)
|
||||
return FALSE;
|
||||
|
||||
tm.tm_hour = hour;
|
||||
tm.tm_min = min;
|
||||
tm.tm_sec = sec;
|
||||
|
||||
time_->tv_usec = 0;
|
||||
|
||||
if (*iso_date == ',' || *iso_date == '.')
|
||||
{
|
||||
glong mul = 100000;
|
||||
|
||||
while (g_ascii_isdigit (*++iso_date))
|
||||
while (mul >= 1 && g_ascii_isdigit (*++iso_date))
|
||||
{
|
||||
time_->tv_usec += (*iso_date - '0') * mul;
|
||||
mul /= 10;
|
||||
}
|
||||
|
||||
/* Skip any remaining digits after we’ve reached our limit of precision. */
|
||||
while (g_ascii_isdigit (*iso_date))
|
||||
iso_date++;
|
||||
}
|
||||
|
||||
/* Now parse the offset and convert tm to a time_t */
|
||||
@ -448,11 +480,24 @@ g_time_val_from_iso8601 (const gchar *iso_date,
|
||||
val = strtoul (iso_date + 1, (char **)&iso_date, 10);
|
||||
|
||||
if (*iso_date == ':')
|
||||
val = 60 * val + strtoul (iso_date + 1, (char **)&iso_date, 10);
|
||||
{
|
||||
/* hh:mm */
|
||||
hour = val;
|
||||
min = strtoul (iso_date + 1, (char **)&iso_date, 10);
|
||||
}
|
||||
else
|
||||
val = 60 * (val / 100) + (val % 100);
|
||||
{
|
||||
/* hhmm */
|
||||
hour = val / 100;
|
||||
min = val % 100;
|
||||
}
|
||||
|
||||
time_->tv_sec = mktime_utc (&tm) + (time_t) (60 * val * sign);
|
||||
if (hour > 99)
|
||||
return FALSE;
|
||||
if (min > 59)
|
||||
return FALSE;
|
||||
|
||||
time_->tv_sec = mktime_utc (&tm) + (time_t) (60 * (60 * hour + min) * sign);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -166,6 +166,7 @@ dist_test_data += \
|
||||
bookmarks/fail-38.xbel \
|
||||
bookmarks/fail-39.xbel \
|
||||
bookmarks/fail-40.xbel \
|
||||
bookmarks/fail-41.xbel \
|
||||
bookmarks/valid-01.xbel \
|
||||
bookmarks/valid-02.xbel \
|
||||
bookmarks/valid-03.xbel \
|
||||
|
1
glib/tests/bookmarks/fail-41.xbel
Normal file
1
glib/tests/bookmarks/fail-41.xbel
Normal file
@ -0,0 +1 @@
|
||||
<xbel version="1.0"><bookmark href=""added="2T0+819855292164632335">
|
@ -144,7 +144,39 @@ test_timeval_from_iso8601 (void)
|
||||
{ FALSE, "2001-10-08Tx", { 0, 0 } },
|
||||
{ FALSE, "2001-10-08T10:11x", { 0, 0 } },
|
||||
{ FALSE, "Wed Dec 19 17:20:20 GMT 2007", { 0, 0 } },
|
||||
{ FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } }
|
||||
{ FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } },
|
||||
{ FALSE, "2T0+819855292164632335", { 0, 0 } },
|
||||
{ TRUE, "2018-08-03T14:08:05.446178377+01:00", { 1533301685, 446178 } },
|
||||
{ FALSE, "2147483648-08-03T14:08:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-13-03T14:08:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-00-03T14:08:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-00T14:08:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-32T14:08:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-03T24:08:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-03T14:60:05.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-03T14:08:63.446178377+01:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-03T14:08:05.446178377+100:00", { 0, 0 } },
|
||||
{ FALSE, "2018-08-03T14:08:05.446178377+01:60", { 0, 0 } },
|
||||
{ TRUE, "20180803T140805.446178377+0100", { 1533301685, 446178 } },
|
||||
{ FALSE, "21474836480803T140805.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20181303T140805.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180003T140805.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180800T140805.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180832T140805.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180803T240805.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180803T146005.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180803T140863.446178377+0100", { 0, 0 } },
|
||||
{ FALSE, "20180803T140805.446178377+10000", { 0, 0 } },
|
||||
{ FALSE, "20180803T140805.446178377+0160", { 0, 0 } },
|
||||
{ TRUE, "+1980-02-22T12:36:00+02:00", { 320063760, 0 } },
|
||||
{ FALSE, "-0005-01-01T00:00:00Z", { 0, 0 } },
|
||||
{ FALSE, "2018-08-06", { 0, 0 } },
|
||||
{ FALSE, "2018-08-06 13:51:00Z", { 0, 0 } },
|
||||
{ TRUE, "20180803T140805,446178377+0100", { 1533301685, 446178 } },
|
||||
{ TRUE, "2018-08-03T14:08:05.446178377-01:00", { 1533308885, 446178 } },
|
||||
{ FALSE, "2018-08-03T14:08:05.446178377 01:00", { 0, 0 } },
|
||||
{ TRUE, "1990-11-01T10:21:17", { 657454877, 0 } },
|
||||
{ TRUE, "1990-11-01T10:21:17 ", { 657454877, 0 } },
|
||||
};
|
||||
GTimeVal out;
|
||||
gboolean success;
|
||||
|
Loading…
Reference in New Issue
Block a user