From d8168d33f3d7139d5aecee9082587fb3a2ec64fc Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Sat, 9 Aug 2025 18:51:06 -0500 Subject: [PATCH] App: Remove use of dangerous localtime() function --- src/App/BackupPolicy.cpp | 26 +++++++++++++++++++++----- tests/src/App/BackupPolicy.cpp | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/App/BackupPolicy.cpp b/src/App/BackupPolicy.cpp index ded6ca83f0..c66b7f4f29 100644 --- a/src/App/BackupPolicy.cpp +++ b/src/App/BackupPolicy.cpp @@ -216,11 +216,27 @@ void BackupPolicy::applyTimeStamp(const std::string& sourcename, const std::stri std::stringstream str; Base::TimeInfo ti = fi.lastModified(); time_t s = ti.getTime_t(); - struct tm* timeinfo = localtime(&s); - char buffer[100]; - - strftime(buffer, sizeof(buffer), saveBackupDateFormat.c_str(), timeinfo); - str << bn << buffer; + std::tm local_tm {}; +#if defined(_WIN32) + localtime_s(&local_tm, &s); // Windows +#else + localtime_r(&s, &local_tm); // POSIX +#endif + constexpr size_t bufferLength = 128; + std::array buffer {}; + if (size_t bytes = std::strftime(buffer.data(), + bufferLength, + saveBackupDateFormat.c_str(), + &local_tm); + bytes == 0) { + // An error here is typically that we over-ran the maximum buffer length ( + // which should be a *very* unusual condition). + Base::Console().error("Failed to create valid backup file name from format string:\n"); + Base::Console().error(saveBackupDateFormat.c_str()); + const auto knownGoodFormat {"%Y-%m-%d_%H-%M-%S"}; + std::strftime(buffer.data(), bufferLength, knownGoodFormat, &local_tm); + } + str << bn << buffer.data(); fn = str.str(); bool done = false; diff --git a/tests/src/App/BackupPolicy.cpp b/tests/src/App/BackupPolicy.cpp index 38f3627d87..33e930e31c 100644 --- a/tests/src/App/BackupPolicy.cpp +++ b/tests/src/App/BackupPolicy.cpp @@ -394,7 +394,7 @@ TEST_F(BackupPolicyTest, TimestampReplacesDotsWithDashes) TEST_F(BackupPolicyTest, DISABLED_TimestampWithInvalidFormatStringThrows) { // THIS TEST IS DISABLED BECAUSE THE CURRENT CODE DOES NOT CORRECTLY HANDLE INVALID FORMAT - // OPERATIONS, AND CRASHES WHEN GIVEN ONE. FIXME. + // OPERATIONS, AND GENERATES UNEXPECTED FILENAMES WHEN GIVEN ONE. FIXME. // Arrange setPolicyTerms(App::BackupPolicy::Policy::TimeStamp, 1, true, "%Q-%W-%E");