summaryrefslogtreecommitdiffstats
path: root/src/fmt/test/fuzzing/float.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/fmt/test/fuzzing/float.cc
parentInitial commit. (diff)
downloadceph-upstream/18.2.2.tar.xz
ceph-upstream/18.2.2.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/fmt/test/fuzzing/float.cc')
-rw-r--r--src/fmt/test/fuzzing/float.cc39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/fmt/test/fuzzing/float.cc b/src/fmt/test/fuzzing/float.cc
new file mode 100644
index 000000000..d4c9e4f57
--- /dev/null
+++ b/src/fmt/test/fuzzing/float.cc
@@ -0,0 +1,39 @@
+// A fuzzer for floating-point formatter.
+// For the license information refer to format.h.
+
+#include <fmt/format.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+#include <stdexcept>
+
+#include "fuzzer-common.h"
+
+void check_round_trip(fmt::string_view format_str, double value) {
+ auto buffer = fmt::memory_buffer();
+ fmt::format_to(std::back_inserter(buffer), format_str, value);
+
+ if (std::isnan(value)) {
+ auto nan = std::signbit(value) ? "-nan" : "nan";
+ if (fmt::string_view(buffer.data(), buffer.size()) != nan)
+ throw std::runtime_error("round trip failure");
+ return;
+ }
+
+ buffer.push_back('\0');
+ char* ptr = nullptr;
+ if (std::strtod(buffer.data(), &ptr) != value)
+ throw std::runtime_error("round trip failure");
+ if (ptr + 1 != buffer.end()) throw std::runtime_error("unparsed output");
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size <= sizeof(double) || !std::numeric_limits<double>::is_iec559)
+ return 0;
+ check_round_trip("{}", assign_from_buf<double>(data));
+ // A larger than necessary precision is used to trigger the fallback
+ // formatter.
+ check_round_trip("{:.50g}", assign_from_buf<double>(data));
+ return 0;
+}