1 // Copyright (c) 2019, Paul Dreik
2 // For the license information refer to format.h.
4 #include <fmt/format.h>
10 #include "fuzzer-common.h"
12 template <typename Item1
, typename Item2
>
13 void invoke_fmt(const uint8_t* data
, size_t size
) {
14 static_assert(sizeof(Item1
) <= fixed_size
, "size1 exceeded");
15 static_assert(sizeof(Item2
) <= fixed_size
, "size2 exceeded");
16 if (size
<= fixed_size
+ fixed_size
) return;
18 const Item1 item1
= assign_from_buf
<Item1
>(data
);
22 const Item2 item2
= assign_from_buf
<Item2
>(data
);
26 auto format_str
= fmt::string_view(as_chars(data
), size
);
27 #if FMT_FUZZ_FORMAT_TO_STRING
28 std::string message
= fmt::format(format_str
, item1
, item2
);
30 auto buf
= fmt::memory_buffer();
31 fmt::format_to(std::back_inserter(buf
), format_str
, item1
, item2
);
35 // For dynamic dispatching to an explicit instantiation.
36 template <typename Callback
> void invoke(int index
, Callback callback
) {
45 using sc
= signed char;
49 using uc
= unsigned char;
56 using us
= unsigned short;
69 using ul
= unsigned long;
79 using LD
= long double;
89 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data
, size_t size
) {
90 if (size
<= 3) return 0;
92 // Switch types depending on the first byte of the input.
93 const auto type1
= data
[0] & 0x0F;
94 const auto type2
= (data
[0] & 0xF0) >> 4;
98 invoke(type1
, [=](auto param1
) {
99 invoke(type2
, [=](auto param2
) {
100 invoke_fmt
<decltype(param1
), decltype(param2
)>(data
, size
);
103 } catch (std::exception
&) {