From 0297a77a506c2b2e344fda6d5e578b5b24177c43 Mon Sep 17 00:00:00 2001 From: superp00t Date: Sun, 30 Jul 2023 14:24:50 -0400 Subject: [PATCH] fix(time): check properly for timestamp + nsec overflows in MakeTime and BreakTime --- bc/time/Time.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/bc/time/Time.cpp b/bc/time/Time.cpp index e45c190..b041934 100644 --- a/bc/time/Time.cpp +++ b/bc/time/Time.cpp @@ -119,6 +119,8 @@ uint64_t Seconds() { } Timestamp MakeTime(const TimeRec& date) { + Timestamp timestamp = 0; + #if defined(WHOA_SYSTEM_WIN) // Win32 implementation FILETIME fileTime = {}; @@ -138,14 +140,7 @@ Timestamp MakeTime(const TimeRec& date) { ul.HighPart = fileTime.dwHighDateTime; ul.LowPart = fileTime.dwLowDateTime; - auto timestamp = FromWinFiletime(ul.QuadPart); - if (timestamp == std::numeric_limits::min() - || timestamp == std::numeric_limits::max()) { - return timestamp; - } - - timestamp += date.nsec; - return timestamp; + timestamp = FromWinFiletime(ul.QuadPart); #endif #if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX) @@ -161,23 +156,29 @@ Timestamp MakeTime(const TimeRec& date) { // Convert date into UNIX timestamp auto unixTime = ::timegm(&t); - auto timestamp = FromUnixTime(unixTime); - if (timestamp == std::numeric_limits< || timestamp == 2147483647L) { + timestamp = FromUnixTime(unixTime); +#endif + // Add nsec to result + auto nsec = date.nsec; + + // overflow check + if ((timestamp + static_cast(nsec)) < timestamp) { return timestamp; } - timestamp += date.nsec; + timestamp += nsec; + return timestamp; -#endif } void BreakTime(Timestamp timestamp, TimeRec& date) { - auto nsec = timestamp % TimeConst::TimestampsPerSecond; + auto mod = (timestamp % TimeConst::TimestampsPerSecond); - if (nsec < 0) { - nsec += TimeConst::TimestampsPerSecond; + auto nsec = static_cast(mod + TimeConst::TimestampsPerSecond); + + if (mod < std::numeric_limits::max()) { + nsec = mod; } - #if defined(WHOA_SYSTEM_WIN) // Win32 implementation ULARGE_INTEGER ul = {};