fix out-of-range float to int conversion in to_nonnegative_int (#4802)

This commit is contained in:
aizu-m 2026-06-17 11:44:58 +05:30 committed by GitHub
parent 1be298e1bd
commit de4c6c502e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 5 additions and 3 deletions

View File

@ -934,10 +934,9 @@ inline auto to_nonnegative_int(T value, Int upper) -> Int {
} }
template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)> template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)>
inline auto to_nonnegative_int(T value, Int upper) -> Int { inline auto to_nonnegative_int(T value, Int upper) -> Int {
auto int_value = static_cast<Int>(value); if (value < 0 || value >= static_cast<T>(upper) + 1)
if (int_value < 0 || value > static_cast<T>(upper))
FMT_THROW(format_error("invalid value")); FMT_THROW(format_error("invalid value"));
return int_value; return static_cast<Int>(value);
} }
constexpr auto pow10(std::uint32_t n) -> long long { constexpr auto pow10(std::uint32_t n) -> long long {

View File

@ -989,6 +989,9 @@ TEST(chrono_test, glibc_extensions) {
TEST(chrono_test, out_of_range) { TEST(chrono_test, out_of_range) {
auto d = std::chrono::duration<unsigned long, std::giga>(538976288); auto d = std::chrono::duration<unsigned long, std::giga>(538976288);
EXPECT_THROW((void)fmt::format("{:%j}", d), fmt::format_error); EXPECT_THROW((void)fmt::format("{:%j}", d), fmt::format_error);
// A floating-point day count that doesn't fit in int.
auto fd = std::chrono::duration<double>(1e300);
EXPECT_THROW((void)fmt::format("{:%j}", fd), fmt::format_error);
} }
TEST(chrono_test, year_month_day) { TEST(chrono_test, year_month_day) {