AK: Add formatting for infinity and NaN

Without this patch, we would end up printing garbage values when we
encountered floating point infinity or NaN values, and also triggered
UBSAN with Clang. This added code models `std::format`'s behavior: the
sign is added the same way as with normal values and the strings 'nan'
and 'inf' are printed.
This commit is contained in:
Daniel Bertalan 2021-08-06 21:47:49 +02:00 committed by Andreas Kling
parent 12dc2c2079
commit 1472f6d986

View file

@ -19,6 +19,7 @@
# include <Kernel/Process.h>
# include <Kernel/Thread.h>
#else
# include <math.h>
# include <stdio.h>
# include <string.h>
#endif
@ -344,6 +345,22 @@ void FormatBuilder::put_f64(
StringBuilder string_builder;
FormatBuilder format_builder { string_builder };
if (isnan(value) || isinf(value)) [[unlikely]] {
if (value < 0.0)
string_builder.append('-');
else if (sign_mode == SignMode::Always)
string_builder.append('+');
else
string_builder.append(' ');
if (isnan(value))
string_builder.append(upper_case ? "NAN"sv : "nan"sv);
else
string_builder.append(upper_case ? "INF"sv : "inf"sv);
format_builder.put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill);
return;
}
bool is_negative = value < 0.0;
if (is_negative)
value = -value;
@ -394,6 +411,22 @@ void FormatBuilder::put_f80(
StringBuilder string_builder;
FormatBuilder format_builder { string_builder };
if (isnan(value) || isinf(value)) [[unlikely]] {
if (value < 0.0l)
string_builder.append('-');
else if (sign_mode == SignMode::Always)
string_builder.append('+');
else
string_builder.append(' ');
if (isnan(value))
string_builder.append(upper_case ? "NAN"sv : "nan"sv);
else
string_builder.append(upper_case ? "INF"sv : "inf"sv);
format_builder.put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill);
return;
}
bool is_negative = value < 0.0l;
if (is_negative)
value = -value;