Branch data Line data Source code
1 : : // Copyright (c) 2015-present The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : #include <prevector.h>
6 : : #include <serialize.h>
7 : : #include <streams.h>
8 : : #include <test/fuzz/FuzzedDataProvider.h>
9 : : #include <test/fuzz/fuzz.h>
10 : :
11 : : #include <ranges>
12 : : #include <vector>
13 : : namespace {
14 : :
15 : : template <unsigned int N, typename T>
16 : : class prevector_tester
17 : : {
18 : : typedef std::vector<T> realtype;
19 : : realtype real_vector;
20 : : realtype real_vector_alt;
21 : :
22 : : typedef prevector<N, T> pretype;
23 : : pretype pre_vector;
24 : : pretype pre_vector_alt;
25 : :
26 : : typedef typename pretype::size_type Size;
27 : :
28 : : public:
29 : 375 : void test() const
30 : : {
31 : 375 : const pretype& const_pre_vector = pre_vector;
32 [ - + + + : 633 : assert(real_vector.size() == pre_vector.size());
- + ]
33 [ - + ]: 375 : assert(real_vector.empty() == pre_vector.empty());
34 [ + + ]: 1384439 : for (Size s = 0; s < real_vector.size(); s++) {
35 [ + + - + ]: 2768128 : assert(real_vector[s] == pre_vector[s]);
36 [ + + - + ]: 2768128 : assert(&(pre_vector[s]) == &(pre_vector.begin()[s]));
37 [ - + ]: 1384064 : assert(&(pre_vector[s]) == &*(pre_vector.begin() + s));
38 [ - + ]: 1384064 : assert(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
39 : : }
40 : : // assert(realtype(pre_vector) == real_vector);
41 [ - + ]: 375 : assert(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
42 [ + + - + ]: 750 : assert(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
43 : 375 : size_t pos = 0;
44 [ + + + + ]: 1384814 : for (const T& v : pre_vector) {
45 [ - + ]: 1384064 : assert(v == real_vector[pos]);
46 : 1384064 : ++pos;
47 : : }
48 [ + + ]: 1384439 : for (const T& v : pre_vector | std::views::reverse) {
49 : 1384064 : --pos;
50 [ - + ]: 1384064 : assert(v == real_vector[pos]);
51 : : }
52 [ + + ]: 1384439 : for (const T& v : const_pre_vector) {
53 [ - + ]: 1384064 : assert(v == real_vector[pos]);
54 : 1384064 : ++pos;
55 : : }
56 [ + + ]: 1384439 : for (const T& v : const_pre_vector | std::views::reverse) {
57 : 1384064 : --pos;
58 [ - + ]: 1384064 : assert(v == real_vector[pos]);
59 : : }
60 : 375 : DataStream ss1{};
61 : 375 : DataStream ss2{};
62 [ + - ]: 375 : ss1 << real_vector;
63 [ + - - + ]: 750 : ss2 << pre_vector;
64 [ - + - + ]: 375 : assert(ss1.size() == ss2.size());
65 [ + + ]: 5537188 : for (Size s = 0; s < ss1.size(); s++) {
66 [ - + ]: 5536813 : assert(ss1[s] == ss2[s]);
67 : : }
68 : 375 : }
69 : :
70 : 22722 : void resize(Size s)
71 : : {
72 : 22722 : real_vector.resize(s);
73 [ - + - + ]: 22722 : assert(real_vector.size() == s);
74 : 22722 : pre_vector.resize(s);
75 [ + + - + ]: 33387 : assert(pre_vector.size() == s);
76 : 22722 : }
77 : :
78 : 10582 : void reserve(Size s)
79 : : {
80 : 10582 : real_vector.reserve(s);
81 [ - + - + ]: 10582 : assert(real_vector.capacity() >= s);
82 : 10582 : pre_vector.reserve(s);
83 [ + + - + ]: 20616 : assert(pre_vector.capacity() >= s);
84 : 10582 : }
85 : :
86 : 34323 : void insert(Size position, const T& value)
87 : : {
88 : 34323 : real_vector.insert(real_vector.begin() + position, value);
89 [ + + ]: 68646 : pre_vector.insert(pre_vector.begin() + position, value);
90 : 34323 : }
91 : :
92 : 26486 : void insert(Size position, Size count, const T& value)
93 : : {
94 : 26486 : real_vector.insert(real_vector.begin() + position, count, value);
95 [ + + ]: 52972 : pre_vector.insert(pre_vector.begin() + position, count, value);
96 : 26486 : }
97 : :
98 : : template <typename I>
99 : 19480 : void insert_range(Size position, I first, I last)
100 : : {
101 : 19480 : real_vector.insert(real_vector.begin() + position, first, last);
102 [ + + ]: 38960 : pre_vector.insert(pre_vector.begin() + position, first, last);
103 : 19480 : }
104 : :
105 : 8516 : void erase(Size position)
106 : : {
107 : 8516 : real_vector.erase(real_vector.begin() + position);
108 [ + + ]: 17032 : pre_vector.erase(pre_vector.begin() + position);
109 : 8516 : }
110 : :
111 : 13842 : void erase(Size first, Size last)
112 : : {
113 : 13842 : real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
114 [ + + ]: 27684 : pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
115 : 13842 : }
116 : :
117 : 7538 : void update(Size pos, const T& value)
118 : : {
119 [ + + ]: 7538 : real_vector[pos] = value;
120 [ + + ]: 7538 : pre_vector[pos] = value;
121 : 7538 : }
122 : :
123 : 11028 : void push_back(const T& value)
124 : : {
125 : 11028 : real_vector.push_back(value);
126 : 11028 : pre_vector.push_back(value);
127 : 11028 : }
128 : :
129 : 10985 : void pop_back()
130 : : {
131 : 10985 : real_vector.pop_back();
132 : 10985 : pre_vector.pop_back();
133 : 10985 : }
134 : :
135 : 11349 : void clear()
136 : : {
137 [ + + ]: 11349 : real_vector.clear();
138 : 11349 : pre_vector.clear();
139 : 11349 : }
140 : :
141 : 25908 : void assign(Size n, const T& value)
142 : : {
143 : 25908 : real_vector.assign(n, value);
144 : 25908 : pre_vector.assign(n, value);
145 : 25908 : }
146 : :
147 : 452489 : Size size() const
148 : : {
149 : 904978 : return real_vector.size();
150 : : }
151 : :
152 : : Size capacity() const
153 : : {
154 : : return pre_vector.capacity();
155 : : }
156 : :
157 : 20690 : void shrink_to_fit()
158 : : {
159 : 20690 : pre_vector.shrink_to_fit();
160 : 20690 : }
161 : :
162 : 15271 : void swap() noexcept
163 : : {
164 : 15271 : real_vector.swap(real_vector_alt);
165 : 15271 : pre_vector.swap(pre_vector_alt);
166 : 15271 : }
167 : :
168 : 29142 : void move()
169 : : {
170 : 29142 : real_vector = std::move(real_vector_alt);
171 [ - + ]: 29142 : real_vector_alt.clear();
172 : 29142 : pre_vector = std::move(pre_vector_alt);
173 : 29142 : pre_vector_alt.clear();
174 : 29142 : }
175 : :
176 : 29555 : void copy()
177 : : {
178 : 29555 : real_vector = real_vector_alt;
179 : 29555 : pre_vector = pre_vector_alt;
180 : 29555 : }
181 : :
182 [ - + ]: 8323 : void resize_uninitialized(realtype values)
183 : : {
184 : 8323 : size_t r = values.size();
185 [ - + ]: 8323 : size_t s = real_vector.size() / 2;
186 [ - + + + ]: 8323 : if (real_vector.capacity() < s + r) {
187 : 3023 : real_vector.reserve(s + r);
188 : : }
189 : 8323 : real_vector.resize(s);
190 : 8323 : pre_vector.resize_uninitialized(s);
191 [ + + ]: 64516 : for (auto v : values) {
192 : 56193 : real_vector.push_back(v);
193 : : }
194 [ + + ]: 8323 : auto p = pre_vector.size();
195 : 8323 : pre_vector.resize_uninitialized(p + r);
196 [ + + ]: 64516 : for (auto v : values) {
197 [ + + ]: 56193 : pre_vector[p] = v;
198 : 56193 : ++p;
199 : : }
200 : 8323 : }
201 : : };
202 : :
203 : : } // namespace
204 : :
205 [ + - ]: 849 : FUZZ_TARGET(prevector)
206 : : {
207 : 375 : FuzzedDataProvider prov(buffer.data(), buffer.size());
208 : 375 : prevector_tester<8, int> test;
209 : :
210 [ + + + + ]: 306115 : LIMITED_WHILE (prov.remaining_bytes(), 3000) {
211 : 383888 : switch (prov.ConsumeIntegralInRange<int>(0, 13 + 3 * (test.size() > 0))) {
[ + + + +
+ + + + +
+ + + + +
+ + + + +
- - + ]
212 : 34323 : case 0: {
213 [ - + ]: 34323 : auto position = prov.ConsumeIntegralInRange<size_t>(0, test.size());
214 : 34323 : auto value = prov.ConsumeIntegral<int>();
215 [ + - ]: 34323 : test.insert(position, value);
216 : : } break;
217 : 22722 : case 1:
218 [ - + + + : 61516 : test.resize(std::max(0, std::min(30, (int)test.size() + prov.ConsumeIntegralInRange<int>(0, 4) - 2)));
+ + + - ]
219 : : break;
220 : 26486 : case 2: {
221 [ - + ]: 26486 : auto position = prov.ConsumeIntegralInRange<size_t>(0, test.size());
222 : 26486 : auto count = 1 + prov.ConsumeBool();
223 : 26486 : auto value = prov.ConsumeIntegral<int>();
224 [ + - ]: 26486 : test.insert(position, count, value);
225 : : } break;
226 : 13842 : case 3: {
227 [ - + ]: 13842 : int del = prov.ConsumeIntegralInRange<int>(0, test.size());
228 [ - + ]: 13842 : int beg = prov.ConsumeIntegralInRange<int>(0, test.size() - del);
229 : 13842 : test.erase(beg, beg + del);
230 : : break;
231 : : }
232 : 11028 : case 4:
233 [ + - ]: 11028 : test.push_back(prov.ConsumeIntegral<int>());
234 : : break;
235 : 19480 : case 5: {
236 : 19480 : int values[4];
237 : 19480 : int num = 1 + prov.ConsumeIntegralInRange<int>(0, 3);
238 [ + + ]: 63011 : for (int k = 0; k < num; ++k) {
239 : 43531 : values[k] = prov.ConsumeIntegral<int>();
240 : : }
241 [ - + + - ]: 19480 : test.insert_range(prov.ConsumeIntegralInRange<size_t>(0, test.size()), values, values + num);
242 : : break;
243 : : }
244 : 8323 : case 6: {
245 : 8323 : int num = 1 + prov.ConsumeIntegralInRange<int>(0, 15);
246 [ + - ]: 8323 : std::vector<int> values(num);
247 [ + + ]: 64516 : for (auto& v : values) {
248 : 56193 : v = prov.ConsumeIntegral<int>();
249 : : }
250 [ + - + - ]: 8323 : test.resize_uninitialized(values);
251 : 8323 : break;
252 : 8323 : }
253 : 10582 : case 7:
254 [ + - ]: 10582 : test.reserve(prov.ConsumeIntegralInRange<size_t>(0, 32767));
255 : : break;
256 : 20690 : case 8:
257 : 20690 : test.shrink_to_fit();
258 : : break;
259 : 11349 : case 9:
260 : 11349 : test.clear();
261 : : break;
262 : 25908 : case 10: {
263 : 25908 : auto n = prov.ConsumeIntegralInRange<size_t>(0, 32767);
264 : 25908 : auto value = prov.ConsumeIntegral<int>();
265 [ + - ]: 25908 : test.assign(n, value);
266 : : } break;
267 : 15271 : case 11:
268 : 15271 : test.swap();
269 : 15271 : break;
270 : 29555 : case 12:
271 [ + - ]: 29555 : test.copy();
272 : : break;
273 : 29142 : case 13:
274 : 29142 : test.move();
275 : : break;
276 : 7538 : case 14: {
277 [ - + ]: 7538 : auto pos = prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1);
278 : 7538 : auto value = prov.ConsumeIntegral<int>();
279 : 7538 : test.update(pos, value);
280 : : } break;
281 : 8516 : case 15:
282 [ - + ]: 8516 : test.erase(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1));
283 : : break;
284 : 10985 : case 16:
285 : 10985 : test.pop_back();
286 : : break;
287 : : }
288 : : }
289 : :
290 [ + - ]: 375 : test.test();
291 : 375 : }
|