Make conversions between std::chrono time_point and string safer by not using "localtime" directly.

coverity_clang_test
Project579 2 years ago
parent 6d3de520e8
commit 5cf2a958eb

@ -639,14 +639,13 @@ std::time_t MwIniImporter::lastWriteTime(const std::filesystem::path& filename,
if (std::filesystem::exists(filename)) if (std::filesystem::exists(filename))
{ {
std::filesystem::path resolved = std::filesystem::canonical(filename); std::filesystem::path resolved = std::filesystem::canonical(filename);
writeTime = Misc::to_time_t(std::filesystem::last_write_time(resolved)); const auto time = std::filesystem::last_write_time(resolved);
writeTime = Misc::toTimeT(time);
// print timestamp // print timestamp
const int size = 1024; const auto str = Misc::fileTimeToString(time, "%x %X");
char timeStrBuffer[size]; if (!str.empty())
if (std::strftime(timeStrBuffer, size, "%x %X", localtime(&writeTime)) > 0) std::cout << "content file: " << resolved << " timestamp = (" << writeTime << ") " << str << std::endl;
std::cout << "content file: " << resolved << " timestamp = (" << writeTime << ") " << timeStrBuffer
<< std::endl;
} }
return writeTime; return writeTime;
} }

@ -30,6 +30,7 @@
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
#include <components/misc/helpviewer.hpp> #include <components/misc/helpviewer.hpp>
#include <components/misc/timeconvert.hpp>
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include "globaldebugprofilemenu.hpp" #include "globaldebugprofilemenu.hpp"
@ -765,11 +766,7 @@ void CSVDoc::View::infoAbout()
#endif #endif
// Get current year // Get current year
time_t now = time(nullptr); const auto copyrightInfo = Misc::timeToString(std::chrono::system_clock::now(), "Copyright © 2008-%Y OpenMW Team");
struct tm tstruct;
char copyrightInfo[40];
tstruct = *localtime(&now);
strftime(copyrightInfo, sizeof(copyrightInfo), "Copyright © 2008-%Y OpenMW Team", &tstruct);
QString aboutText = QString( QString aboutText = QString(
"<p style=\"white-space: pre-wrap;\">" "<p style=\"white-space: pre-wrap;\">"
@ -788,7 +785,8 @@ void CSVDoc::View::infoAbout()
.arg(versionInfo, .arg(versionInfo,
tr("OpenMW-CS is a content file editor for OpenMW, a modern, free and open source game " tr("OpenMW-CS is a content file editor for OpenMW, a modern, free and open source game "
"engine."), "engine."),
tr(copyrightInfo), tr("Home Page:"), tr("Forum:"), tr("Bug Tracker:"), tr("IRC:")); tr(copyrightInfo.c_str()), tr("Home Page:"), tr("Forum:"), tr("Bug Tracker:"),
tr("IRC:"));
QMessageBox::about(this, "About OpenMW-CS", aboutText); QMessageBox::about(this, "About OpenMW-CS", aboutText);
} }

@ -410,11 +410,8 @@ namespace MWGui
throw std::runtime_error("Can't find selected slot"); throw std::runtime_error("Can't find selected slot");
std::stringstream text; std::stringstream text;
time_t time = Misc::to_time_t(mCurrentSlot->mTimeStamp);
struct tm* timeinfo;
timeinfo = localtime(&time);
text << std::put_time(timeinfo, "%Y.%m.%d %T") << "\n"; text << Misc::fileTimeToString(mCurrentSlot->mTimeStamp, "%Y.%m.%d %T") << "\n";
text << "#{sLevel} " << mCurrentSlot->mProfile.mPlayerLevel << "\n"; text << "#{sLevel} " << mCurrentSlot->mProfile.mPlayerLevel << "\n";
text << "#{sCell=" << mCurrentSlot->mProfile.mPlayerCell << "}\n"; text << "#{sCell=" << mCurrentSlot->mProfile.mPlayerCell << "}\n";

@ -223,18 +223,20 @@ bool Config::LauncherSettings::isEqual(const QStringList& list1, const QStringLi
QString Config::LauncherSettings::makeNewContentListName() QString Config::LauncherSettings::makeNewContentListName()
{ {
// basically, use date and time as the name e.g. YYYY-MM-DDThh:mm:ss // basically, use date and time as the name e.g. YYYY-MM-DDThh:mm:ss
time_t rawtime; auto rawtime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
struct tm* timeinfo; tm timeinfo{};
#ifdef _WIN32
time(&rawtime); (void)localtime_s(&timeinfo, &rawtime);
timeinfo = localtime(&rawtime); #else
(void)localtime_r(&rawtime, &timeinfo);
#endif
int base = 10; int base = 10;
QChar zeroPad('0'); QChar zeroPad('0');
return QString("%1-%2-%3T%4:%5:%6") return QString("%1-%2-%3T%4:%5:%6")
.arg(timeinfo->tm_year + 1900, 4) .arg(timeinfo.tm_year + 1900, 4)
.arg(timeinfo->tm_mon + 1, 2, base, zeroPad) .arg(timeinfo.tm_mon + 1, 2, base, zeroPad)
.arg(timeinfo->tm_mday, 2, base, zeroPad) .arg(timeinfo.tm_mday, 2, base, zeroPad)
.arg(timeinfo->tm_hour, 2, base, zeroPad) .arg(timeinfo.tm_hour, 2, base, zeroPad)
.arg(timeinfo->tm_min, 2, base, zeroPad) .arg(timeinfo.tm_min, 2, base, zeroPad)
.arg(timeinfo->tm_sec, 2, base, zeroPad); .arg(timeinfo.tm_sec, 2, base, zeroPad);
} }

@ -99,7 +99,13 @@ namespace Debug
prefix[0] = '['; prefix[0] = '[';
const auto now = std::chrono::system_clock::now(); const auto now = std::chrono::system_clock::now();
const auto time = std::chrono::system_clock::to_time_t(now); const auto time = std::chrono::system_clock::to_time_t(now);
prefixSize = std::strftime(prefix + 1, sizeof(prefix) - 1, "%T", std::localtime(&time)) + 1; tm time_info{};
#ifdef _WIN32
(void)localtime_s(&time_info, &time);
#else
(void)localtime_r(&time, &time_info);
#endif
prefixSize = std::strftime(prefix + 1, sizeof(prefix) - 1, "%T", &time_info) + 1;
char levelLetter = " EWIVD*"[int(level)]; char levelLetter = " EWIVD*"[int(level)];
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
prefixSize += snprintf(prefix + prefixSize, sizeof(prefix) - prefixSize, ".%03u %c] ", prefixSize += snprintf(prefix + prefixSize, sizeof(prefix) - prefixSize, ".%03u %c] ",

@ -2,17 +2,39 @@
#define OPENMW_COMPONENTS_MISC_TIMECONVERT_H #define OPENMW_COMPONENTS_MISC_TIMECONVERT_H
#include <chrono> #include <chrono>
#include <ctime>
namespace Misc namespace Misc
{ {
template <typename TP> template <typename TP>
inline std::time_t to_time_t(TP tp) inline std::time_t toTimeT(TP tp)
{ {
using namespace std::chrono; using namespace std::chrono;
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now()); auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
return system_clock::to_time_t(sctp); return system_clock::to_time_t(sctp);
} }
inline std::string timeTToString(const std::time_t tp, const char* fmt)
{
tm time_info{};
#ifdef _WIN32
(void)localtime_s(&time_info, &tp);
#else
(void)localtime_r(&tp, &time_info);
#endif
std::stringstream out;
out << std::put_time(&time_info, fmt);
return out.str();
}
inline std::string fileTimeToString(const std::filesystem::file_time_type& tp, const char* fmt)
{
return timeTToString(toTimeT(tp), fmt);
}
inline std::string timeToString(const std::chrono::system_clock::time_point& tp, const char* fmt)
{
return timeTToString(std::chrono::system_clock::to_time_t(tp), fmt);
}
} // namespace Misc } // namespace Misc
#endif #endif

Loading…
Cancel
Save