Fix a UB in chrono

This commit is contained in:
Victor Zverovich 2022-01-09 10:22:36 -08:00
parent c06bef7273
commit d9f045fba1
2 changed files with 20 additions and 3 deletions

View File

@ -1663,7 +1663,7 @@ struct chrono_formatter {
out = format_decimal<char_type>(out, n, num_digits).end;
}
template <class Duration> void write_fractional_seconds(Duration d) {
template <typename Duration> void write_fractional_seconds(Duration d) {
constexpr auto num_fractional_digits =
count_fractional_digits(Duration::period::num, Duration::period::den);
@ -1770,8 +1770,22 @@ struct chrono_formatter {
if (handle_nan_inf()) return;
if (ns == numeric_system::standard) {
if (std::is_floating_point<rep>::value) {
auto num_fractional_digits =
count_fractional_digits(Period::num, Period::den);
auto buf = memory_buffer();
format_to(std::back_inserter(buf), runtime("{:.{}f}"),
std::fmod(val * static_cast<rep>(Period::num) /
static_cast<rep>(Period::den),
60),
num_fractional_digits);
if (negative) *out++ = '-';
if (buf.size() < 2 || buf[1] == '.') *out++ = '0';
out = std::copy(buf.begin(), buf.end(), out);
} else {
write(second(), 2);
write_fractional_seconds(std::chrono::duration<rep, Period>{val});
write_fractional_seconds(std::chrono::duration<rep, Period>(val));
}
return;
}
auto time = tm();

View File

@ -557,6 +557,9 @@ TEST(chrono_test, special_durations) {
"03:33");
EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}),
"03:33:20");
EXPECT_EQ("44.000000000000",
fmt::format("{:%S}", std::chrono::duration<float, std::pico>(
1.54213895E+26)));
}
TEST(chrono_test, unsigned_duration) {