Skip to content

Commit

Permalink
Detect overflow on large precision
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Dec 5, 2021
1 parent c240d98 commit 215f21a
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
7 changes: 6 additions & 1 deletion include/fmt/format-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,12 @@ FMT_INLINE FMT_CONSTEXPR20 digits::result grisu_gen_digits(
if (handler.fixed) {
// Adjust fixed precision by exponent because it is relative to decimal
// point.
handler.precision += exp + handler.exp10;
int precision_offset = exp + handler.exp10;
if (precision_offset > 0 &&
handler.precision > max_value<int>() - precision_offset) {
throw format_error("number is too big");

This comment has been minimized.

Copy link
@bsongis

bsongis Dec 6, 2021

Is it possible to use FMT_THROW here without breaking everything?

This comment has been minimized.

Copy link
@vitaut

vitaut Dec 6, 2021

Author Contributor

Not sure what you mean but this replaces a UB with a throw.

This comment has been minimized.

Copy link
@bsongis-frsky

bsongis-frsky Dec 10, 2021

Indeed, but some do use your lib on small devices, without exceptions, I think FMT_THROW will deal with this use case?

This comment has been minimized.

Copy link
@vitaut

vitaut Dec 10, 2021

Author Contributor

Yes, FMT_THROW will become an assert if exceptions are disabled.

}
handler.precision += precision_offset;
// Check if precision is satisfied just by leading zeros, e.g.
// format("{:.2f}", 0.001) gives "0.00" without generating any digits.
if (handler.precision <= 0) {
Expand Down
3 changes: 3 additions & 0 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,9 @@ TEST(format_test, precision) {
EXPECT_THROW_MSG((void)fmt::format(runtime("{:.{}e}"), 42.0,
fmt::detail::max_value<int>()),
format_error, "number is too big");
EXPECT_THROW_MSG(
(void)fmt::format("{:.2147483646f}", -2.2121295195081227E+304),
format_error, "number is too big");

EXPECT_EQ("st", fmt::format("{0:.2}", "str"));
}
Expand Down
2 changes: 1 addition & 1 deletion test/fuzzing/float.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

void check_round_trip(fmt::string_view format_str, double value) {
auto buffer = fmt::memory_buffer();
fmt::format_to(buffer, format_str, value);
fmt::format_to(std::back_inserter(buffer), format_str, value);

if (std::isnan(value)) {
auto nan = std::signbit(value) ? "-nan" : "nan";
Expand Down

0 comments on commit 215f21a

Please sign in to comment.