diff --git a/glib/gdatetime.c b/glib/gdatetime.c index a2409f410..56eb8cc58 100644 --- a/glib/gdatetime.c +++ b/glib/gdatetime.c @@ -52,6 +52,7 @@ #define _GNU_SOURCE 1 #endif +#include #include #include @@ -1213,7 +1214,11 @@ get_iso8601_seconds (const gchar *text, gsize length, gdouble *value) divisor *= 10; } - *value = v / divisor; + v = v / divisor; + if (!isfinite (v)) + return FALSE; + + *value = v; return TRUE; } @@ -1585,6 +1590,7 @@ g_date_time_new (GTimeZone *tz, day < 1 || day > days_in_months[GREGORIAN_LEAP (year)][month] || hour < 0 || hour > 23 || minute < 0 || minute > 59 || + !isfinite (seconds) || seconds < 0.0 || seconds >= 60.0) return NULL; diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c index 2da3dcc8b..0e6b5bdd3 100644 --- a/glib/tests/gdatetime.c +++ b/glib/tests/gdatetime.c @@ -18,6 +18,7 @@ #include "config.h" +#include #include #include #include @@ -799,6 +800,12 @@ test_GDateTime_new_from_iso8601 (void) /* Timezone hours two digits */ dt = g_date_time_new_from_iso8601 ("2016-08-24T22-2Z", NULL); g_assert_null (dt); + + /* Ordinal date (YYYYDDD), space separator, and then time as HHMMSS,SSS + * The interesting bit is that the seconds field is so long as to parse as + * NaN */ + dt = g_date_time_new_from_iso8601 ("0005306 000001,666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666600080000-00", NULL); + g_assert_null (dt); } typedef struct { @@ -1273,6 +1280,8 @@ test_GDateTime_new_full (void) g_date_time_unref (dt); dt = g_date_time_new_utc (2016, 12, 32, 22, 10, 42); g_assert_null (dt); + dt = g_date_time_new_utc (2020, 12, 9, 14, 49, NAN); + g_assert_null (dt); } static void