From 784e2a7b4227657229fcac4532977b99508ee5cb Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 23 Dec 2021 09:59:15 -0800 Subject: [PATCH] Fix an overflow when formatting very large durations --- include/fmt/chrono.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 5285d420..5f38a8c9 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1663,15 +1663,16 @@ struct chrono_formatter { if (std::ratio_less::value) { *out++ = '.'; + // Don't convert long double to integer seconds to avoid overflow. + using sec = conditional_t< + std::is_same::value, + std::chrono::duration, std::chrono::seconds>; + auto fractional = detail::abs(d) - std::chrono::duration_cast(d); const auto subseconds = std::chrono::treat_as_floating_point< typename subsecond_precision::rep>::value - ? (detail::abs(d) - - std::chrono::duration_cast(d)) - .count() - : std::chrono::duration_cast( - detail::abs(d) - - std::chrono::duration_cast(d)) + ? fractional.count() + : std::chrono::duration_cast(fractional) .count(); uint32_or_64_or_128_t n = to_unsigned(to_nonnegative_int(subseconds, max_value()));