1 // Copyright (c) 2019, Paul Dreik
2 // For the license information refer to format.h.
4 #include <fmt/chrono.h>
8 #include "fuzzer-common.h"
10 template <typename Period
, typename Rep
>
11 void invoke_inner(fmt::string_view format_str
, Rep rep
) {
12 auto value
= std::chrono::duration
<Rep
, Period
>(rep
);
14 #if FMT_FUZZ_FORMAT_TO_STRING
15 std::string message
= fmt::format(format_str
, value
);
17 auto buf
= fmt::memory_buffer();
18 fmt::format_to(std::back_inserter(buf
), format_str
, value
);
20 } catch (std::exception
&) {
24 // Rep is a duration's representation type.
25 template <typename Rep
>
26 void invoke_outer(const uint8_t* data
, size_t size
, int period
) {
27 // Always use a fixed location of the data.
28 static_assert(sizeof(Rep
) <= fixed_size
, "fixed size is too small");
29 if (size
<= fixed_size
+ 1) return;
31 const Rep rep
= assign_from_buf
<Rep
>(data
);
35 // data is already allocated separately in libFuzzer so reading past the end
36 // will most likely be detected anyway.
37 const auto format_str
= fmt::string_view(as_chars(data
), size
);
39 // yocto, zepto, zetta and yotta are not handled.
42 invoke_inner
<std::atto
>(format_str
, rep
);
45 invoke_inner
<std::femto
>(format_str
, rep
);
48 invoke_inner
<std::pico
>(format_str
, rep
);
51 invoke_inner
<std::nano
>(format_str
, rep
);
54 invoke_inner
<std::micro
>(format_str
, rep
);
57 invoke_inner
<std::milli
>(format_str
, rep
);
60 invoke_inner
<std::centi
>(format_str
, rep
);
63 invoke_inner
<std::deci
>(format_str
, rep
);
66 invoke_inner
<std::deca
>(format_str
, rep
);
69 invoke_inner
<std::kilo
>(format_str
, rep
);
72 invoke_inner
<std::mega
>(format_str
, rep
);
75 invoke_inner
<std::giga
>(format_str
, rep
);
78 invoke_inner
<std::tera
>(format_str
, rep
);
81 invoke_inner
<std::peta
>(format_str
, rep
);
84 invoke_inner
<std::exa
>(format_str
, rep
);
89 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data
, size_t size
) {
90 if (size
<= 4) return 0;
92 const auto representation
= data
[0];
93 const auto period
= data
[1];
97 switch (representation
) {
99 invoke_outer
<char>(data
, size
, period
);
102 invoke_outer
<signed char>(data
, size
, period
);
105 invoke_outer
<unsigned char>(data
, size
, period
);
108 invoke_outer
<short>(data
, size
, period
);
111 invoke_outer
<unsigned short>(data
, size
, period
);
114 invoke_outer
<int>(data
, size
, period
);
117 invoke_outer
<unsigned int>(data
, size
, period
);
120 invoke_outer
<long>(data
, size
, period
);
123 invoke_outer
<unsigned long>(data
, size
, period
);
126 invoke_outer
<float>(data
, size
, period
);
129 invoke_outer
<double>(data
, size
, period
);
132 invoke_outer
<long double>(data
, size
, period
);