Fix possible integer overflow in `parse_date_time`

`g_date_time_to_unix` returns a `gint64`.  Since 27c07280b1 ("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 <jeremy@azazel.net>
This commit is contained in:
Jeremy Sowden 2024-04-12 22:39:48 +01:00
parent 32d73260d3
commit e6b4e0e45e
3 changed files with 13 additions and 5 deletions

View File

@ -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<gint64>(t, 0);
}

View File

@ -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

View File

@ -62,7 +62,7 @@ test_date_basic()
}
g_setenv("TZ", hki, TRUE);
std::vector<std::tuple<const char*, bool/*is_first*/, int64_t>> cases = {{
std::vector<std::tuple<const char*, bool/*is_first*/, ::time_t>> 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}
}};