diff options
| author | 2026-06-10 09:55:54 +0100 | |
|---|---|---|
| committer | 2026-06-10 11:07:51 +0100 | |
| commit | 9533f488fdc166637cd271f54d1b56b3dc850ec5 (patch) | |
| tree | 4eaf32b063309745fe872a1dfc6bfb030d2d6d8a /src/helperfuncs.cpp | |
| parent | Fix storing configuration tags in the wrong container type. (diff) | |
Switch Time::ToString to use re-entrant time functions.
This is safer and has a cleaner failure path (if the functions fail
the struct remains zero initialised).
I have also removed some legacy checks that aren't needed now we
use strftime not asctime.
Diffstat (limited to 'src/helperfuncs.cpp')
| -rw-r--r-- | src/helperfuncs.cpp | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index 01d49cc41..0f113e9f5 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -491,32 +491,34 @@ std::string Duration::ToLongString(unsigned long duration, bool brief) std::string Time::ToString(time_t curtime, const char* format, bool utc) { -#ifdef _WIN32 - if (curtime < 0) - curtime = 0; -#endif + if (!format) + format = Time::DEFAULT_SHORT; - struct tm* timeinfo = utc ? gmtime(&curtime) : localtime(&curtime); - if (!timeinfo) + tm time_info{}; + if (utc ? !gmtime_r(&curtime, &time_info) : !localtime_r(&curtime, &time_info)) [[unlikely]] { + // If we've reached this point then either the time_t represents a year + // that can't be represented by tm_year (i.e. the year 2038 problem on + // 32-bit systems) or we are running on Windows which clamps the valid + // years on 64-bit systems to 1970-3000. There's not a lot we can do to + // give a correct timestamp here so we just return the UNIX epoch as + // that should never fail. curtime = 0; - timeinfo = localtime(&curtime); + if (utc) + gmtime_r(&curtime, &time_info); + else + localtime_r(&curtime, &time_info); } - // If the calculated year exceeds four digits or is less than the year 1000, - // the behavior of asctime() is undefined - if (timeinfo->tm_year + 1900 > 9999) - timeinfo->tm_year = 9999 - 1900; - else if (timeinfo->tm_year + 1900 < 1000) - timeinfo->tm_year = 0; - - // This is the default format used by asctime without the terminating new line. - if (!format) - format = Time::DEFAULT_SHORT; - - char buffer[512]; - if (!strftime(buffer, sizeof(buffer), format, timeinfo)) + static char buffer[512]; + if (!strftime(buffer, sizeof(buffer), format, &time_info)) [[unlikely]] + { + // If we've reached this point then the buffer is not big enough to + // contain the formatted date. This probably will never happen because + // we give it a large buffer but in the cases it does happen we null + // terminate the buffer so the returned string is empty. buffer[0] = '\0'; + } return buffer; } |
