1 // Copyright (c) 2019, Paul Dreik
2 // For the license information refer to format.h.
4 #include <fmt/chrono.h>
10 #include "fuzzer-common.h"
13 void invoke_fmt(const uint8_t* data
, size_t size
, unsigned arg_name_size
) {
14 static_assert(sizeof(T
) <= fixed_size
, "fixed_size too small");
15 if (size
<= fixed_size
) return;
16 const T value
= assign_from_buf
<T
>(data
);
20 if (arg_name_size
<= 0 || arg_name_size
>= size
) return;
21 data_to_string
arg_name(data
, arg_name_size
, true);
22 data
+= arg_name_size
;
23 size
-= arg_name_size
;
25 data_to_string
format_str(data
, size
);
27 #if FMT_FUZZ_FORMAT_TO_STRING
29 fmt::format(format_str
.get(), fmt::arg(arg_name
.data(), value
));
31 fmt::memory_buffer out
;
32 fmt::format_to(std::back_inserter(out
), format_str
.get(),
33 fmt::arg(arg_name
.data(), value
));
35 } catch (std::exception
&) {
39 // For dynamic dispatching to an explicit instantiation.
40 template <typename Callback
> void invoke(int type
, Callback callback
) {
49 using sc
= signed char;
53 using uc
= unsigned char;
60 using us
= unsigned short;
73 using ul
= unsigned long;
83 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 type
= data
[0] & 0x0F;
94 const unsigned arg_name_size
= (data
[0] & 0xF0) >> 4;
98 invoke(type
, [=](auto arg
) {
99 invoke_fmt
<decltype(arg
)>(data
, size
, arg_name_size
);