mirror of
https://github.com/catchorg/Catch2.git
synced 2025-01-10 11:53:30 +01:00
Fix crash when stringifying pre 1970 dates on Windows
`gmtime*` on Windows fails on dates pre 1970, and because we didn't check the return code, we would then pass invalid `tm` struct to `strftime` causing it to assert. Closes #2944
This commit is contained in:
parent
a3b67a3abe
commit
b0d0aa43e6
@ -634,7 +634,11 @@ struct ratio_string<std::milli> {
|
|||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
std::tm timeInfo = {};
|
std::tm timeInfo = {};
|
||||||
gmtime_s(&timeInfo, &converted);
|
const auto err = gmtime_s(&timeInfo, &converted);
|
||||||
|
if ( err ) {
|
||||||
|
return "gmtime from provided timepoint has failed. This "
|
||||||
|
"happens e.g. with pre-1970 dates using Microsoft libc";
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
std::tm* timeInfo = std::gmtime(&converted);
|
std::tm* timeInfo = std::gmtime(&converted);
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,10 +7,13 @@
|
|||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
#include <catch2/internal/catch_enum_values_registry.hpp>
|
#include <catch2/internal/catch_enum_values_registry.hpp>
|
||||||
|
#include <catch2/matchers/catch_matchers_string.hpp>
|
||||||
#include <catch2/matchers/catch_matchers_vector.hpp>
|
#include <catch2/matchers/catch_matchers_vector.hpp>
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include <catch2/catch_template_test_macros.hpp>
|
#include <catch2/catch_template_test_macros.hpp>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
enum class EnumClass3 { Value1, Value2, Value3, Value4 };
|
enum class EnumClass3 { Value1, Value2, Value3, Value4 };
|
||||||
|
|
||||||
struct UsesSentinel {
|
struct UsesSentinel {
|
||||||
@ -95,3 +98,23 @@ TEMPLATE_TEST_CASE( "Stringifying char arrays with statically known sizes",
|
|||||||
TestType no_null_terminator[3] = { 'a', 'b', 'c' };
|
TestType no_null_terminator[3] = { 'a', 'b', 'c' };
|
||||||
CHECK( ::Catch::Detail::stringify( no_null_terminator ) == R"("abc")"s );
|
CHECK( ::Catch::Detail::stringify( no_null_terminator ) == R"("abc")"s );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "#2944 - Stringifying dates before 1970 should not crash", "[.approvals]" ) {
|
||||||
|
using Catch::Matchers::Equals;
|
||||||
|
using Days = std::chrono::duration<int32_t, std::ratio<86400>>;
|
||||||
|
using SysDays = std::chrono::time_point<std::chrono::system_clock, Days>;
|
||||||
|
Catch::StringMaker<std::chrono::system_clock::time_point> sm;
|
||||||
|
|
||||||
|
// Check simple date first
|
||||||
|
const SysDays post1970{ Days{ 1 } };
|
||||||
|
auto converted_post = sm.convert( post1970 );
|
||||||
|
REQUIRE( converted_post == "1970-01-02T00:00:00Z" );
|
||||||
|
|
||||||
|
const SysDays pre1970{ Days{ -1 } };
|
||||||
|
auto converted_pre = sm.convert( pre1970 );
|
||||||
|
REQUIRE_THAT(
|
||||||
|
converted_pre,
|
||||||
|
Equals( "1969-12-31T00:00:00Z" ) ||
|
||||||
|
Equals( "gmtime from provided timepoint has failed. This "
|
||||||
|
"happens e.g. with pre-1970 dates using Microsoft libc" ) );
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user