Merge pull request #12587 from AdmiralCurtiss/localtime

Core: Fix crash when inspecting a savestate with a timestamp that causes localtime() to error out
This commit is contained in:
Mai 2024-02-18 17:12:29 -05:00 committed by GitHub
commit 27415b0ba1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 46 additions and 2 deletions

View File

@ -138,6 +138,8 @@ add_library(common
Thread.h
Timer.cpp
Timer.h
TimeUtil.cpp
TimeUtil.h
TraversalClient.cpp
TraversalClient.h
TraversalProto.h

View File

@ -0,0 +1,24 @@
// Copyright 2024 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Common/TimeUtil.h"
#include <ctime>
#include <optional>
namespace Common
{
std::optional<std::tm> Localtime(std::time_t time)
{
std::tm local_time;
#ifdef _MSC_VER
if (localtime_s(&local_time, &time) != 0)
return std::nullopt;
#else
std::tm* result = localtime_r(&time, &local_time);
if (result != &local_time)
return std::nullopt;
#endif
return local_time;
}
} // Namespace Common

View File

@ -0,0 +1,13 @@
// Copyright 2024 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ctime>
#include <optional>
namespace Common
{
// Threadsafe and error-checking variant of std::localtime()
std::optional<std::tm> Localtime(std::time_t time);
} // Namespace Common

View File

@ -29,6 +29,7 @@
#include "Common/IOFile.h"
#include "Common/MsgHandler.h"
#include "Common/Thread.h"
#include "Common/TimeUtil.h"
#include "Common/Timer.h"
#include "Common/Version.h"
#include "Common/WorkQueueThread.h"
@ -282,10 +283,12 @@ static std::string SystemTimeAsDoubleToString(double time)
{
// revert adjustments from GetSystemTimeAsDouble() to get a normal Unix timestamp again
const time_t seconds = static_cast<time_t>(time) + DOUBLE_TIME_OFFSET;
const tm local_time = fmt::localtime(seconds);
const auto local_time = Common::Localtime(seconds);
if (!local_time)
return "";
// fmt is locale agnostic by default, so explicitly use current locale.
return fmt::format(std::locale{""}, "{:%x %X}", local_time);
return fmt::format(std::locale{""}, "{:%x %X}", *local_time);
}
static std::string MakeStateFilename(int number);

View File

@ -161,6 +161,7 @@
<ClInclude Include="Common\SymbolDB.h" />
<ClInclude Include="Common\Thread.h" />
<ClInclude Include="Common\Timer.h" />
<ClInclude Include="Common\TimeUtil.h" />
<ClInclude Include="Common\TraversalClient.h" />
<ClInclude Include="Common\TraversalProto.h" />
<ClInclude Include="Common\TypeUtils.h" />
@ -832,6 +833,7 @@
<ClCompile Include="Common\SymbolDB.cpp" />
<ClCompile Include="Common\Thread.cpp" />
<ClCompile Include="Common\Timer.cpp" />
<ClCompile Include="Common\TimeUtil.cpp" />
<ClCompile Include="Common\TraversalClient.cpp" />
<ClCompile Include="Common\UPnP.cpp" />
<ClCompile Include="Common\WindowsRegistry.cpp" />