1*5c90c05cSAndroid Build Coastguard Worker // Copyright (c) 2019, Paul Dreik
2*5c90c05cSAndroid Build Coastguard Worker // For the license information refer to format.h.
3*5c90c05cSAndroid Build Coastguard Worker
4*5c90c05cSAndroid Build Coastguard Worker #include <fmt/format.h>
5*5c90c05cSAndroid Build Coastguard Worker
6*5c90c05cSAndroid Build Coastguard Worker #include <cstdint>
7*5c90c05cSAndroid Build Coastguard Worker #include <exception>
8*5c90c05cSAndroid Build Coastguard Worker #include <string>
9*5c90c05cSAndroid Build Coastguard Worker
10*5c90c05cSAndroid Build Coastguard Worker #include "fuzzer-common.h"
11*5c90c05cSAndroid Build Coastguard Worker
12*5c90c05cSAndroid Build Coastguard Worker template <typename Item1, typename Item2>
invoke_fmt(const uint8_t * data,size_t size)13*5c90c05cSAndroid Build Coastguard Worker void invoke_fmt(const uint8_t* data, size_t size) {
14*5c90c05cSAndroid Build Coastguard Worker static_assert(sizeof(Item1) <= fixed_size, "size1 exceeded");
15*5c90c05cSAndroid Build Coastguard Worker static_assert(sizeof(Item2) <= fixed_size, "size2 exceeded");
16*5c90c05cSAndroid Build Coastguard Worker if (size <= fixed_size + fixed_size) return;
17*5c90c05cSAndroid Build Coastguard Worker
18*5c90c05cSAndroid Build Coastguard Worker const Item1 item1 = assign_from_buf<Item1>(data);
19*5c90c05cSAndroid Build Coastguard Worker data += fixed_size;
20*5c90c05cSAndroid Build Coastguard Worker size -= fixed_size;
21*5c90c05cSAndroid Build Coastguard Worker
22*5c90c05cSAndroid Build Coastguard Worker const Item2 item2 = assign_from_buf<Item2>(data);
23*5c90c05cSAndroid Build Coastguard Worker data += fixed_size;
24*5c90c05cSAndroid Build Coastguard Worker size -= fixed_size;
25*5c90c05cSAndroid Build Coastguard Worker
26*5c90c05cSAndroid Build Coastguard Worker auto format_str = fmt::string_view(as_chars(data), size);
27*5c90c05cSAndroid Build Coastguard Worker #if FMT_FUZZ_FORMAT_TO_STRING
28*5c90c05cSAndroid Build Coastguard Worker std::string message = fmt::format(format_str, item1, item2);
29*5c90c05cSAndroid Build Coastguard Worker #else
30*5c90c05cSAndroid Build Coastguard Worker auto buf = fmt::memory_buffer();
31*5c90c05cSAndroid Build Coastguard Worker fmt::format_to(std::back_inserter(buf), format_str, item1, item2);
32*5c90c05cSAndroid Build Coastguard Worker #endif
33*5c90c05cSAndroid Build Coastguard Worker }
34*5c90c05cSAndroid Build Coastguard Worker
35*5c90c05cSAndroid Build Coastguard Worker // For dynamic dispatching to an explicit instantiation.
invoke(int index,Callback callback)36*5c90c05cSAndroid Build Coastguard Worker template <typename Callback> void invoke(int index, Callback callback) {
37*5c90c05cSAndroid Build Coastguard Worker switch (index) {
38*5c90c05cSAndroid Build Coastguard Worker case 0:
39*5c90c05cSAndroid Build Coastguard Worker callback(bool());
40*5c90c05cSAndroid Build Coastguard Worker break;
41*5c90c05cSAndroid Build Coastguard Worker case 1:
42*5c90c05cSAndroid Build Coastguard Worker callback(char());
43*5c90c05cSAndroid Build Coastguard Worker break;
44*5c90c05cSAndroid Build Coastguard Worker case 2:
45*5c90c05cSAndroid Build Coastguard Worker using sc = signed char;
46*5c90c05cSAndroid Build Coastguard Worker callback(sc());
47*5c90c05cSAndroid Build Coastguard Worker break;
48*5c90c05cSAndroid Build Coastguard Worker case 3:
49*5c90c05cSAndroid Build Coastguard Worker using uc = unsigned char;
50*5c90c05cSAndroid Build Coastguard Worker callback(uc());
51*5c90c05cSAndroid Build Coastguard Worker break;
52*5c90c05cSAndroid Build Coastguard Worker case 4:
53*5c90c05cSAndroid Build Coastguard Worker callback(short());
54*5c90c05cSAndroid Build Coastguard Worker break;
55*5c90c05cSAndroid Build Coastguard Worker case 5:
56*5c90c05cSAndroid Build Coastguard Worker using us = unsigned short;
57*5c90c05cSAndroid Build Coastguard Worker callback(us());
58*5c90c05cSAndroid Build Coastguard Worker break;
59*5c90c05cSAndroid Build Coastguard Worker case 6:
60*5c90c05cSAndroid Build Coastguard Worker callback(int());
61*5c90c05cSAndroid Build Coastguard Worker break;
62*5c90c05cSAndroid Build Coastguard Worker case 7:
63*5c90c05cSAndroid Build Coastguard Worker callback(unsigned());
64*5c90c05cSAndroid Build Coastguard Worker break;
65*5c90c05cSAndroid Build Coastguard Worker case 8:
66*5c90c05cSAndroid Build Coastguard Worker callback(long());
67*5c90c05cSAndroid Build Coastguard Worker break;
68*5c90c05cSAndroid Build Coastguard Worker case 9:
69*5c90c05cSAndroid Build Coastguard Worker using ul = unsigned long;
70*5c90c05cSAndroid Build Coastguard Worker callback(ul());
71*5c90c05cSAndroid Build Coastguard Worker break;
72*5c90c05cSAndroid Build Coastguard Worker case 10:
73*5c90c05cSAndroid Build Coastguard Worker callback(float());
74*5c90c05cSAndroid Build Coastguard Worker break;
75*5c90c05cSAndroid Build Coastguard Worker case 11:
76*5c90c05cSAndroid Build Coastguard Worker callback(double());
77*5c90c05cSAndroid Build Coastguard Worker break;
78*5c90c05cSAndroid Build Coastguard Worker case 12:
79*5c90c05cSAndroid Build Coastguard Worker using LD = long double;
80*5c90c05cSAndroid Build Coastguard Worker callback(LD());
81*5c90c05cSAndroid Build Coastguard Worker break;
82*5c90c05cSAndroid Build Coastguard Worker case 13:
83*5c90c05cSAndroid Build Coastguard Worker using ptr = void*;
84*5c90c05cSAndroid Build Coastguard Worker callback(ptr());
85*5c90c05cSAndroid Build Coastguard Worker break;
86*5c90c05cSAndroid Build Coastguard Worker }
87*5c90c05cSAndroid Build Coastguard Worker }
88*5c90c05cSAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)89*5c90c05cSAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
90*5c90c05cSAndroid Build Coastguard Worker if (size <= 3) return 0;
91*5c90c05cSAndroid Build Coastguard Worker
92*5c90c05cSAndroid Build Coastguard Worker // Switch types depending on the first byte of the input.
93*5c90c05cSAndroid Build Coastguard Worker const auto type1 = data[0] & 0x0F;
94*5c90c05cSAndroid Build Coastguard Worker const auto type2 = (data[0] & 0xF0) >> 4;
95*5c90c05cSAndroid Build Coastguard Worker data++;
96*5c90c05cSAndroid Build Coastguard Worker size--;
97*5c90c05cSAndroid Build Coastguard Worker try {
98*5c90c05cSAndroid Build Coastguard Worker invoke(type1, [=](auto param1) {
99*5c90c05cSAndroid Build Coastguard Worker invoke(type2, [=](auto param2) {
100*5c90c05cSAndroid Build Coastguard Worker invoke_fmt<decltype(param1), decltype(param2)>(data, size);
101*5c90c05cSAndroid Build Coastguard Worker });
102*5c90c05cSAndroid Build Coastguard Worker });
103*5c90c05cSAndroid Build Coastguard Worker } catch (std::exception&) {
104*5c90c05cSAndroid Build Coastguard Worker }
105*5c90c05cSAndroid Build Coastguard Worker return 0;
106*5c90c05cSAndroid Build Coastguard Worker }
107