xref: /aosp_15_r20/external/fmtlib/test/fuzzing/two-args.cc (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
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