Report out-of-range errors in chrono

This commit is contained in:
Victor Zverovich 2023-12-10 07:26:45 -08:00
parent 640e0c02d4
commit 9048add999
2 changed files with 15 additions and 10 deletions

View File

@ -1049,10 +1049,10 @@ inline void tzset_once() {
// Converts value to Int and checks that it's in the range [0, upper).
template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline Int to_nonnegative_int(T value, Int upper) {
FMT_ASSERT(std::is_unsigned<Int>::value ||
(value >= 0 && to_unsigned(value) <= to_unsigned(upper)),
"invalid value");
(void)upper;
if (!std::is_unsigned<Int>::value &&
(value < 0 || to_unsigned(value) > to_unsigned(upper))) {
FMT_THROW(fmt::format_error("chrono value is out of range"));
}
return static_cast<Int>(value);
}
template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)>

View File

@ -740,8 +740,8 @@ TEST(chrono_test, special_durations) {
EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}),
"03:33:20");
EXPECT_EQ("01.234",
fmt::format("{:.3%S}", std::chrono::duration<float, std::pico>(
1.234e12)));
fmt::format("{:.3%S}",
std::chrono::duration<float, std::pico>(1.234e12)));
}
TEST(chrono_test, unsigned_duration) {
@ -864,8 +864,8 @@ TEST(chrono_test, timestamps_ratios) {
EXPECT_EQ(fmt::format("{:%M:%S}", t1), "01:07.890");
std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>
t2(std::chrono::minutes(7));
std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes> t2(
std::chrono::minutes(7));
EXPECT_EQ(fmt::format("{:%M:%S}", t2), "07:00");
@ -1023,3 +1023,8 @@ TEST(chrono_test, glibc_extensions) {
EXPECT_EQ(fmt::format("{:%-S}", d), "3.140000");
}
}
TEST(chrono_test, out_of_range) {
auto d = std::chrono::duration<unsigned long, std::giga>(538976288);
EXPECT_THROW((void)fmt::format("{:%j}", d), fmt::format_error);
}