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