]> git.proxmox.com Git - ceph.git/blob - ceph/src/fmt/test/fuzzing/sprintf.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / fmt / test / fuzzing / sprintf.cpp
1 // Copyright (c) 2019, Paul Dreik
2 // License: see LICENSE.rst in the fmt root directory
3 #include <fmt/format.h>
4 #include <fmt/printf.h>
5 #include <cstdint>
6 #include <stdexcept>
7
8 #include "fuzzer_common.h"
9
10 using fmt_fuzzer::Nfixed;
11
12 template <typename Item1, typename Item2>
13 void invoke_fmt(const uint8_t* Data, size_t Size) {
14 constexpr auto N1 = sizeof(Item1);
15 constexpr auto N2 = sizeof(Item2);
16 static_assert(N1 <= Nfixed, "size1 exceeded");
17 static_assert(N2 <= Nfixed, "size2 exceeded");
18 if (Size <= Nfixed + Nfixed) {
19 return;
20 }
21 Item1 item1 = fmt_fuzzer::assignFromBuf<Item1>(Data);
22 Data += Nfixed;
23 Size -= Nfixed;
24
25 Item2 item2 = fmt_fuzzer::assignFromBuf<Item2>(Data);
26 Data += Nfixed;
27 Size -= Nfixed;
28
29 auto fmtstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size);
30
31 #if FMT_FUZZ_FORMAT_TO_STRING
32 std::string message = fmt::format(fmtstring, item1, item2);
33 #else
34 fmt::memory_buffer message;
35 fmt::format_to(message, fmtstring, item1, item2);
36 #endif
37 }
38
39 // for dynamic dispatching to an explicit instantiation
40 template <typename Callback> void invoke(int index, Callback callback) {
41 switch (index) {
42 case 0:
43 callback(bool{});
44 break;
45 case 1:
46 callback(char{});
47 break;
48 case 2:
49 using sc = signed char;
50 callback(sc{});
51 break;
52 case 3:
53 using uc = unsigned char;
54 callback(uc{});
55 break;
56 case 4:
57 callback(short{});
58 break;
59 case 5:
60 using us = unsigned short;
61 callback(us{});
62 break;
63 case 6:
64 callback(int{});
65 break;
66 case 7:
67 callback(unsigned{});
68 break;
69 case 8:
70 callback(long{});
71 break;
72 case 9:
73 using ul = unsigned long;
74 callback(ul{});
75 break;
76 case 10:
77 callback(float{});
78 break;
79 case 11:
80 callback(double{});
81 break;
82 case 12:
83 using LD = long double;
84 callback(LD{});
85 break;
86 case 13:
87 using ptr = void*;
88 callback(ptr{});
89 break;
90 }
91 }
92
93 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
94 if (Size <= 3) {
95 return 0;
96 }
97
98 // switch types depending on the first byte of the input
99 const auto first = Data[0] & 0x0F;
100 const auto second = (Data[0] & 0xF0) >> 4;
101 Data++;
102 Size--;
103
104 auto outer = [=](auto param1) {
105 auto inner = [=](auto param2) {
106 invoke_fmt<decltype(param1), decltype(param2)>(Data, Size);
107 };
108 invoke(second, inner);
109 };
110
111 try {
112 invoke(first, outer);
113 } catch (std::exception& /*e*/) {
114 }
115 return 0;
116 }