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