From e6b4e0e45e430fe0e4770213fc72cc09472fc026 Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Fri, 12 Apr 2024 22:39:48 +0100 Subject: [PATCH] Fix possible integer overflow in `parse_date_time` `g_date_time_to_unix` returns a `gint64`. Since 27c07280b15d ("utils: replace time_to_string with fmt-based formatting"), `parse_date_time` has returned a `time_t`, which has historically been a 32-bit type. There is, therefore, the possibility of integer over- and underflow. Define `TIME_MIN` and `TIME_MAX` based on the size of `time_t` and clamp the return value of `parse_date_time` between these. Signed-off-by: Jeremy Sowden --- lib/utils/mu-utils.cc | 11 ++++++++--- lib/utils/mu-utils.hh | 3 +++ lib/utils/tests/test-utils.cc | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/utils/mu-utils.cc b/lib/utils/mu-utils.cc index d3fea3f6..ab1a999d 100644 --- a/lib/utils/mu-utils.cc +++ b/lib/utils/mu-utils.cc @@ -489,11 +489,11 @@ Mu::parse_date_time(const std::string& dstr, bool is_first, bool utc) { struct tm tbuf{}; GDateTime *dtime{}; - ::time_t t; + gint64 t; /* one-sided dates */ if (dstr.empty()) - return is_first ? 0 : G_MAXINT64; + return is_first ? 0 : TIME_MAX; else if (dstr == "today" || dstr == "now") return special_date_time(dstr, is_first); else if (dstr.find_first_of("ymdwhMs") != std::string::npos) @@ -531,7 +531,12 @@ Mu::parse_date_time(const std::string& dstr, bool is_first, bool utc) t = g_date_time_to_unix(dtime); g_date_time_unref(dtime); - return std::max<::time_t>(t, 0); + if (t > TIME_MAX) + t = TIME_MAX; + if (t < TIME_MIN) + t = TIME_MIN; + + return std::max(t, 0); } diff --git a/lib/utils/mu-utils.hh b/lib/utils/mu-utils.hh index cef84b4f..6cd02ebb 100644 --- a/lib/utils/mu-utils.hh +++ b/lib/utils/mu-utils.hh @@ -47,6 +47,9 @@ namespace Mu { +constexpr const auto TIME_MIN = sizeof(::time_t) == 8 ? G_MININT64 : G_MININT32; +constexpr const auto TIME_MAX = sizeof(::time_t) == 8 ? G_MAXINT64 : G_MAXINT32; + /* * Separator characters used in various places; importantly, * they are not used in UTF-8 diff --git a/lib/utils/tests/test-utils.cc b/lib/utils/tests/test-utils.cc index 993c875c..c52184de 100644 --- a/lib/utils/tests/test-utils.cc +++ b/lib/utils/tests/test-utils.cc @@ -62,7 +62,7 @@ test_date_basic() } g_setenv("TZ", hki, TRUE); - std::vector> cases = {{ + std::vector> cases = {{ {"2015-09-18T09:10:23", true, 1442556623}, {"1972-12-14T09:10:23", true, 93165023}, {"1972-12-14T09:10", true, 93165000}, @@ -82,7 +82,7 @@ test_date_basic() // {"fnorb", true, -1}, // {"fnorb", false, -1}, - {"", false, G_MAXINT64}, + {"", false, TIME_MAX}, {"", true, 0} }};