gdatetime: Fix integer overflow when parsing very long ISO8601 inputs

This will only happen with invalid (or maliciously invalid) potential
ISO8601 strings, but `g_date_time_new_from_iso8601()` needs to be robust
against that.

Prevent `length` overflowing by correctly defining it as a `size_t`.
Similarly for `date_length`, but additionally track its validity in a
boolean rather than as its sign.

Spotted by chamalsl as #YWH-PGM9867-43.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This commit is contained in:
Philip Withnall 2025-02-18 16:44:58 +00:00
parent d705612505
commit 8d60d7dc16
No known key found for this signature in database
GPG Key ID: C5C42CFB268637CA

View File

@ -1540,7 +1540,8 @@ parse_iso8601_time (const gchar *text, gsize length,
GDateTime *
g_date_time_new_from_iso8601 (const gchar *text, GTimeZone *default_tz)
{
gint length, date_length = -1;
size_t length, date_length = 0;
gboolean date_length_set = FALSE;
gint hour = 0, minute = 0;
gdouble seconds = 0.0;
GTimeZone *tz = NULL;
@ -1551,11 +1552,14 @@ g_date_time_new_from_iso8601 (const gchar *text, GTimeZone *default_tz)
/* Count length of string and find date / time separator ('T', 't', or ' ') */
for (length = 0; text[length] != '\0'; length++)
{
if (date_length < 0 && (text[length] == 'T' || text[length] == 't' || text[length] == ' '))
date_length = length;
if (!date_length_set && (text[length] == 'T' || text[length] == 't' || text[length] == ' '))
{
date_length = length;
date_length_set = TRUE;
}
}
if (date_length < 0)
if (!date_length_set)
return NULL;
if (!parse_iso8601_time (text + date_length + 1, length - (date_length + 1),