xref: /aosp_15_r20/external/fmtlib/test/fuzzing/named-arg.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/chrono.h>
5*5c90c05cSAndroid Build Coastguard Worker 
6*5c90c05cSAndroid Build Coastguard Worker #include <cstdint>
7*5c90c05cSAndroid Build Coastguard Worker #include <type_traits>
8*5c90c05cSAndroid Build Coastguard Worker #include <vector>
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 T>
invoke_fmt(const uint8_t * data,size_t size,unsigned arg_name_size)13*5c90c05cSAndroid Build Coastguard Worker void invoke_fmt(const uint8_t* data, size_t size, unsigned arg_name_size) {
14*5c90c05cSAndroid Build Coastguard Worker   static_assert(sizeof(T) <= fixed_size, "fixed_size too small");
15*5c90c05cSAndroid Build Coastguard Worker   if (size <= fixed_size) return;
16*5c90c05cSAndroid Build Coastguard Worker   const T value = assign_from_buf<T>(data);
17*5c90c05cSAndroid Build Coastguard Worker   data += fixed_size;
18*5c90c05cSAndroid Build Coastguard Worker   size -= fixed_size;
19*5c90c05cSAndroid Build Coastguard Worker 
20*5c90c05cSAndroid Build Coastguard Worker   if (arg_name_size <= 0 || arg_name_size >= size) return;
21*5c90c05cSAndroid Build Coastguard Worker   data_to_string arg_name(data, arg_name_size, true);
22*5c90c05cSAndroid Build Coastguard Worker   data += arg_name_size;
23*5c90c05cSAndroid Build Coastguard Worker   size -= arg_name_size;
24*5c90c05cSAndroid Build Coastguard Worker 
25*5c90c05cSAndroid Build Coastguard Worker   data_to_string format_str(data, size);
26*5c90c05cSAndroid Build Coastguard Worker   try {
27*5c90c05cSAndroid Build Coastguard Worker #if FMT_FUZZ_FORMAT_TO_STRING
28*5c90c05cSAndroid Build Coastguard Worker     std::string message =
29*5c90c05cSAndroid Build Coastguard Worker         fmt::format(format_str.get(), fmt::arg(arg_name.data(), value));
30*5c90c05cSAndroid Build Coastguard Worker #else
31*5c90c05cSAndroid Build Coastguard Worker     fmt::memory_buffer out;
32*5c90c05cSAndroid Build Coastguard Worker     fmt::format_to(std::back_inserter(out), format_str.get(),
33*5c90c05cSAndroid Build Coastguard Worker                    fmt::arg(arg_name.data(), value));
34*5c90c05cSAndroid Build Coastguard Worker #endif
35*5c90c05cSAndroid Build Coastguard Worker   } catch (std::exception&) {
36*5c90c05cSAndroid Build Coastguard Worker   }
37*5c90c05cSAndroid Build Coastguard Worker }
38*5c90c05cSAndroid Build Coastguard Worker 
39*5c90c05cSAndroid Build Coastguard Worker // For dynamic dispatching to an explicit instantiation.
invoke(int type,Callback callback)40*5c90c05cSAndroid Build Coastguard Worker template <typename Callback> void invoke(int type, Callback callback) {
41*5c90c05cSAndroid Build Coastguard Worker   switch (type) {
42*5c90c05cSAndroid Build Coastguard Worker   case 0:
43*5c90c05cSAndroid Build Coastguard Worker     callback(bool());
44*5c90c05cSAndroid Build Coastguard Worker     break;
45*5c90c05cSAndroid Build Coastguard Worker   case 1:
46*5c90c05cSAndroid Build Coastguard Worker     callback(char());
47*5c90c05cSAndroid Build Coastguard Worker     break;
48*5c90c05cSAndroid Build Coastguard Worker   case 2:
49*5c90c05cSAndroid Build Coastguard Worker     using sc = signed char;
50*5c90c05cSAndroid Build Coastguard Worker     callback(sc());
51*5c90c05cSAndroid Build Coastguard Worker     break;
52*5c90c05cSAndroid Build Coastguard Worker   case 3:
53*5c90c05cSAndroid Build Coastguard Worker     using uc = unsigned char;
54*5c90c05cSAndroid Build Coastguard Worker     callback(uc());
55*5c90c05cSAndroid Build Coastguard Worker     break;
56*5c90c05cSAndroid Build Coastguard Worker   case 4:
57*5c90c05cSAndroid Build Coastguard Worker     callback(short());
58*5c90c05cSAndroid Build Coastguard Worker     break;
59*5c90c05cSAndroid Build Coastguard Worker   case 5:
60*5c90c05cSAndroid Build Coastguard Worker     using us = unsigned short;
61*5c90c05cSAndroid Build Coastguard Worker     callback(us());
62*5c90c05cSAndroid Build Coastguard Worker     break;
63*5c90c05cSAndroid Build Coastguard Worker   case 6:
64*5c90c05cSAndroid Build Coastguard Worker     callback(int());
65*5c90c05cSAndroid Build Coastguard Worker     break;
66*5c90c05cSAndroid Build Coastguard Worker   case 7:
67*5c90c05cSAndroid Build Coastguard Worker     callback(unsigned());
68*5c90c05cSAndroid Build Coastguard Worker     break;
69*5c90c05cSAndroid Build Coastguard Worker   case 8:
70*5c90c05cSAndroid Build Coastguard Worker     callback(long());
71*5c90c05cSAndroid Build Coastguard Worker     break;
72*5c90c05cSAndroid Build Coastguard Worker   case 9:
73*5c90c05cSAndroid Build Coastguard Worker     using ul = unsigned long;
74*5c90c05cSAndroid Build Coastguard Worker     callback(ul());
75*5c90c05cSAndroid Build Coastguard Worker     break;
76*5c90c05cSAndroid Build Coastguard Worker   case 10:
77*5c90c05cSAndroid Build Coastguard Worker     callback(float());
78*5c90c05cSAndroid Build Coastguard Worker     break;
79*5c90c05cSAndroid Build Coastguard Worker   case 11:
80*5c90c05cSAndroid Build Coastguard Worker     callback(double());
81*5c90c05cSAndroid Build Coastguard Worker     break;
82*5c90c05cSAndroid Build Coastguard Worker   case 12:
83*5c90c05cSAndroid Build Coastguard Worker     using LD = long double;
84*5c90c05cSAndroid Build Coastguard Worker     callback(LD());
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 type = data[0] & 0x0F;
94*5c90c05cSAndroid Build Coastguard Worker   const unsigned arg_name_size = (data[0] & 0xF0) >> 4;
95*5c90c05cSAndroid Build Coastguard Worker   data++;
96*5c90c05cSAndroid Build Coastguard Worker   size--;
97*5c90c05cSAndroid Build Coastguard Worker 
98*5c90c05cSAndroid Build Coastguard Worker   invoke(type, [=](auto arg) {
99*5c90c05cSAndroid Build Coastguard Worker     invoke_fmt<decltype(arg)>(data, size, arg_name_size);
100*5c90c05cSAndroid Build Coastguard Worker   });
101*5c90c05cSAndroid Build Coastguard Worker   return 0;
102*5c90c05cSAndroid Build Coastguard Worker }
103