fix unchecked float to integral conversion in detail::duration_cast by aizu-m · Pull Request #4985 · fmtlib/fmt · GitHub
Skip to content

fix unchecked float to integral conversion in detail::duration_cast - #4985

Open
aizu-m wants to merge 1 commit into
fmtlib:mainfrom
aizu-m:chrono-mixed-duration-cast
Open

aizu-m wants to merge 1 commit into
fmtlib:mainfrom
aizu-m:chrono-mixed-duration-cast

Conversation

@aizu-m

@aizu-m aizu-m commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

UBSan, clang -fsanitize=undefined, when formatting a time point with a floating-point rep:

__chrono/duration.h:75:63: runtime error: 1e+300 is outside the range of representable values of type 'long'
__chrono/duration.h:75:63: runtime error: nan is outside the range of representable values of type 'long long'

Repro:

using fsec = std::chrono::duration<double>;
fmt::format("{:%T}", fmt::sys_time<fsec>(fsec(1e300)));
fmt::format("{:%T}", fmt::sys_time<fsec>(fsec(NAN)));  // prints "00:00:00an"

The mixed integer <-> float overload of detail::duration_cast delegates to std::chrono::duration_cast, so to_time_t and the sys_time / local_time formatters convert the seconds count with an unchecked static_cast. Only the float to integral direction can overflow, so the overload is split: integer to float keeps the plain cast, and float to integral range-checks the count before casting (which also rejects NaN) and throws like the other checked overloads, with the same boundary handling as to_nonnegative_int (#4802). is_similar_arithmetic_type had no remaining users and is removed.

@aizu-m
aizu-m requested a review from vitaut as a code owner October 14, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant