summaryrefslogtreecommitdiffstats
path: root/src/fmt/test/fuzzing/two_args.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fmt/test/fuzzing/two_args.cpp')
-rw-r--r--src/fmt/test/fuzzing/two_args.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/fmt/test/fuzzing/two_args.cpp b/src/fmt/test/fuzzing/two_args.cpp
new file mode 100644
index 000000000..af3495ce8
--- /dev/null
+++ b/src/fmt/test/fuzzing/two_args.cpp
@@ -0,0 +1,112 @@
+// Copyright (c) 2019, Paul Dreik
+// License: see LICENSE.rst in the fmt root directory
+#include <fmt/format.h>
+#include <cstdint>
+#include <stdexcept>
+#include <type_traits>
+
+#include "fuzzer_common.h"
+
+constexpr auto Nfixed = fmt_fuzzer::Nfixed;
+
+template <typename Item1, typename Item2>
+void invoke_fmt(const uint8_t* Data, size_t Size) {
+ constexpr auto N1 = sizeof(Item1);
+ constexpr auto N2 = sizeof(Item2);
+ static_assert(N1 <= Nfixed, "size1 exceeded");
+ static_assert(N2 <= Nfixed, "size2 exceeded");
+ if (Size <= Nfixed + Nfixed) {
+ return;
+ }
+ const Item1 item1 = fmt_fuzzer::assignFromBuf<Item1>(Data);
+ Data += Nfixed;
+ Size -= Nfixed;
+
+ const Item2 item2 = fmt_fuzzer::assignFromBuf<Item2>(Data);
+ Data += Nfixed;
+ Size -= Nfixed;
+
+ auto fmtstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size);
+
+#if FMT_FUZZ_FORMAT_TO_STRING
+ std::string message = fmt::format(fmtstring, item1, item2);
+#else
+ fmt::memory_buffer message;
+ fmt::format_to(message, fmtstring, item1, item2);
+#endif
+}
+
+// for dynamic dispatching to an explicit instantiation
+template <typename Callback> void invoke(int index, Callback callback) {
+ switch (index) {
+ case 0:
+ callback(bool{});
+ break;
+ case 1:
+ callback(char{});
+ break;
+ case 2:
+ using sc = signed char;
+ callback(sc{});
+ break;
+ case 3:
+ using uc = unsigned char;
+ callback(uc{});
+ break;
+ case 4:
+ callback(short{});
+ break;
+ case 5:
+ using us = unsigned short;
+ callback(us{});
+ break;
+ case 6:
+ callback(int{});
+ break;
+ case 7:
+ callback(unsigned{});
+ break;
+ case 8:
+ callback(long{});
+ break;
+ case 9:
+ using ul = unsigned long;
+ callback(ul{});
+ break;
+ case 10:
+ callback(float{});
+ break;
+ case 11:
+ callback(double{});
+ break;
+ case 12:
+ using LD = long double;
+ callback(LD{});
+ break;
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ if (Size <= 3) {
+ return 0;
+ }
+
+ // switch types depending on the first byte of the input
+ const auto first = Data[0] & 0x0F;
+ const auto second = (Data[0] & 0xF0) >> 4;
+ Data++;
+ Size--;
+
+ auto outer = [=](auto param1) {
+ auto inner = [=](auto param2) {
+ invoke_fmt<decltype(param1), decltype(param2)>(Data, Size);
+ };
+ invoke(second, inner);
+ };
+
+ try {
+ invoke(first, outer);
+ } catch (std::exception& /*e*/) {
+ }
+ return 0;
+}