]> git.proxmox.com Git - ceph.git/blob - ceph/src/fmt/test/fuzzing/one_arg.cpp
buildsys: switch source download to quincy
[ceph.git] / ceph / src / fmt / test / fuzzing / one_arg.cpp
1 // Copyright (c) 2019, Paul Dreik
2 // License: see LICENSE.rst in the fmt root directory
3
4 #include <fmt/core.h>
5 #include <cstdint>
6 #include <stdexcept>
7 #include <type_traits>
8 #include <vector>
9
10 #include <fmt/chrono.h>
11 #include "fuzzer_common.h"
12
13 using fmt_fuzzer::Nfixed;
14
15 template <typename Item>
16 void invoke_fmt(const uint8_t* Data, size_t Size) {
17 constexpr auto N = sizeof(Item);
18 static_assert(N <= Nfixed, "Nfixed is too small");
19 if (Size <= Nfixed) {
20 return;
21 }
22 const Item item = fmt_fuzzer::assignFromBuf<Item>(Data);
23 Data += Nfixed;
24 Size -= Nfixed;
25
26 #if FMT_FUZZ_SEPARATE_ALLOCATION
27 // allocates as tight as possible, making it easier to catch buffer overruns.
28 std::vector<char> fmtstringbuffer(Size);
29 std::memcpy(fmtstringbuffer.data(), Data, Size);
30 auto fmtstring = fmt::string_view(fmtstringbuffer.data(), Size);
31 #else
32 auto fmtstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size);
33 #endif
34
35 #if FMT_FUZZ_FORMAT_TO_STRING
36 std::string message = fmt::format(fmtstring, item);
37 #else
38 fmt::memory_buffer message;
39 fmt::format_to(message, fmtstring, item);
40 #endif
41 }
42
43 void invoke_fmt_time(const uint8_t* Data, size_t Size) {
44 using Item = std::time_t;
45 constexpr auto N = sizeof(Item);
46 static_assert(N <= Nfixed, "Nfixed too small");
47 if (Size <= Nfixed) {
48 return;
49 }
50 const Item item = fmt_fuzzer::assignFromBuf<Item>(Data);
51 Data += Nfixed;
52 Size -= Nfixed;
53 #if FMT_FUZZ_SEPARATE_ALLOCATION
54 // allocates as tight as possible, making it easier to catch buffer overruns.
55 std::vector<char> fmtstringbuffer(Size);
56 std::memcpy(fmtstringbuffer.data(), Data, Size);
57 auto fmtstring = fmt::string_view(fmtstringbuffer.data(), Size);
58 #else
59 auto fmtstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size);
60 #endif
61 auto* b = std::localtime(&item);
62 if (b) {
63 #if FMT_FUZZ_FORMAT_TO_STRING
64 std::string message = fmt::format(fmtstring, *b);
65 #else
66 fmt::memory_buffer message;
67 fmt::format_to(message, fmtstring, *b);
68 #endif
69 }
70 }
71
72 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
73 if (Size <= 3) {
74 return 0;
75 }
76
77 const auto first = Data[0];
78 Data++;
79 Size--;
80
81 try {
82 switch (first) {
83 case 0:
84 invoke_fmt<bool>(Data, Size);
85 break;
86 case 1:
87 invoke_fmt<char>(Data, Size);
88 break;
89 case 2:
90 invoke_fmt<unsigned char>(Data, Size);
91 break;
92 case 3:
93 invoke_fmt<signed char>(Data, Size);
94 break;
95 case 4:
96 invoke_fmt<short>(Data, Size);
97 break;
98 case 5:
99 invoke_fmt<unsigned short>(Data, Size);
100 break;
101 case 6:
102 invoke_fmt<int>(Data, Size);
103 break;
104 case 7:
105 invoke_fmt<unsigned int>(Data, Size);
106 break;
107 case 8:
108 invoke_fmt<long>(Data, Size);
109 break;
110 case 9:
111 invoke_fmt<unsigned long>(Data, Size);
112 break;
113 case 10:
114 invoke_fmt<float>(Data, Size);
115 break;
116 case 11:
117 invoke_fmt<double>(Data, Size);
118 break;
119 case 12:
120 invoke_fmt<long double>(Data, Size);
121 break;
122 case 13:
123 invoke_fmt_time(Data, Size);
124 break;
125 default:
126 break;
127 }
128 } catch (std::exception& /*e*/) {
129 }
130 return 0;
131 }