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