From 2e715844bb14f57ce7f9db9ac957046b916853ee Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sat, 1 Aug 2015 16:41:03 -0400 Subject: [PATCH] Restrict the range of year: to within the range of chrono::minutes. * This prevents overflow when adding minutes to day_point when minutes is stored in 32 bits. * Also added static checks on the range of hours and seconds. If these static checks fire, the range of year should be further reduced. * This does not impact gcc at all. It impacts clang only when targeting 32 bit architectures. And it fixes overflow on Visual Studio. * Thanks much to https://github.com/gmcode for the herculean effort in tracking this down. --- date.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/date.h b/date.h index 89a159f..6b771f2 100644 --- a/date.h +++ b/date.h @@ -6,6 +6,7 @@ // http://creativecommons.org/licenses/by/4.0/ #include +#include #if !(__cplusplus >= 201402) # include #endif @@ -1161,7 +1162,12 @@ inline year year::min() noexcept { - return year{std::numeric_limits::min()}; + using namespace std::chrono; + static_assert(sizeof(seconds)*CHAR_BIT >= 41, "seconds may overflow"); + static_assert(sizeof(hours)*CHAR_BIT >= 30, "hours may overflow"); + return sizeof(minutes)*CHAR_BIT < 34 ? + year{1970} + duration_cast(minutes::min()) : + year{std::numeric_limits::min()}; } CONSTCD11 @@ -1169,7 +1175,12 @@ inline year year::max() noexcept { - return year{std::numeric_limits::max()}; + using namespace std::chrono; + static_assert(sizeof(seconds)*CHAR_BIT >= 41, "seconds may overflow"); + static_assert(sizeof(hours)*CHAR_BIT >= 30, "hours may overflow"); + return sizeof(minutes)*CHAR_BIT < 34 ? + year{1969} + duration_cast(minutes::max()) : + year{std::numeric_limits::max()}; } CONSTCD11