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