/root/bitcoin/src/test/fuzz/util.cpp
Line | Count | Source |
1 | | // Copyright (c) 2021-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 <consensus/amount.h> |
6 | | #include <pubkey.h> |
7 | | #include <test/fuzz/util.h> |
8 | | #include <test/util/script.h> |
9 | | #include <util/check.h> |
10 | | #include <util/overflow.h> |
11 | | #include <util/rbf.h> |
12 | | #include <util/time.h> |
13 | | |
14 | | #include <memory> |
15 | | |
16 | | std::vector<uint8_t> ConstructPubKeyBytes(FuzzedDataProvider& fuzzed_data_provider, std::span<const uint8_t> byte_data, const bool compressed) noexcept |
17 | 3.72M | { |
18 | 3.72M | uint8_t pk_type; |
19 | 3.72M | if (compressed) { Branch (19:9): [True: 3.18M, False: 538k]
|
20 | 3.18M | pk_type = fuzzed_data_provider.PickValueInArray({0x02, 0x03}); |
21 | 3.18M | } else { |
22 | 538k | pk_type = fuzzed_data_provider.PickValueInArray({0x04, 0x06, 0x07}); |
23 | 538k | } |
24 | 3.72M | std::vector<uint8_t> pk_data{byte_data.begin(), byte_data.begin() + (compressed ? CPubKey::COMPRESSED_SIZE : CPubKey::SIZE)}; Branch (24:74): [True: 3.18M, False: 538k]
|
25 | 3.72M | pk_data[0] = pk_type; |
26 | 3.72M | return pk_data; |
27 | 3.72M | } |
28 | | |
29 | | CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max) noexcept |
30 | 3.84M | { |
31 | 3.84M | return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, max.value_or(MAX_MONEY)); |
32 | 3.84M | } |
33 | | |
34 | | NodeSeconds ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min, const std::optional<int64_t>& max) noexcept |
35 | 3.27M | { |
36 | | // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime. |
37 | 3.27M | static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z").value()}; |
38 | 3.27M | static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z").value()}; |
39 | 3.27M | return NodeSeconds{ConsumeDuration<std::chrono::seconds>(fuzzed_data_provider, min.value_or(time_min) * 1s, max.value_or(time_max) * 1s)}; |
40 | 3.27M | } |
41 | | |
42 | | CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<Txid>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept |
43 | 748k | { |
44 | 748k | CMutableTransaction tx_mut; |
45 | 748k | const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool(); |
46 | 748k | tx_mut.version = fuzzed_data_provider.ConsumeBool() ? Branch (46:22): [True: 644k, False: 103k]
|
47 | 644k | CTransaction::CURRENT_VERSION : |
48 | 748k | fuzzed_data_provider.ConsumeIntegral<uint32_t>(); |
49 | 748k | tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); |
50 | 748k | const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in); |
51 | 748k | const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_out); |
52 | 1.87M | for (int i = 0; i < num_in; ++i) { Branch (52:21): [True: 1.12M, False: 748k]
|
53 | 1.12M | const auto& txid_prev = prevout_txids ? Branch (53:33): [True: 1.09M, False: 29.1k]
|
54 | 1.09M | PickValue(fuzzed_data_provider, *prevout_txids) : |
55 | 1.12M | Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)); |
56 | 1.12M | const auto index_out = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, max_num_out); |
57 | 1.12M | const auto sequence = ConsumeSequence(fuzzed_data_provider); |
58 | 1.12M | const auto script_sig = p2wsh_op_true ? CScript{} : ConsumeScript(fuzzed_data_provider); Branch (58:33): [True: 908k, False: 215k]
|
59 | 1.12M | CScriptWitness script_wit; |
60 | 1.12M | if (p2wsh_op_true) { Branch (60:13): [True: 908k, False: 215k]
|
61 | 908k | script_wit.stack = std::vector<std::vector<uint8_t>>{WITNESS_STACK_ELEM_OP_TRUE}; |
62 | 908k | } else { |
63 | 215k | script_wit = ConsumeScriptWitness(fuzzed_data_provider); |
64 | 215k | } |
65 | 1.12M | CTxIn in; |
66 | 1.12M | in.prevout = COutPoint{txid_prev, index_out}; |
67 | 1.12M | in.nSequence = sequence; |
68 | 1.12M | in.scriptSig = script_sig; |
69 | 1.12M | in.scriptWitness = script_wit; |
70 | | |
71 | 1.12M | tx_mut.vin.push_back(in); |
72 | 1.12M | } |
73 | 1.98M | for (int i = 0; i < num_out; ++i) { Branch (73:21): [True: 1.23M, False: 748k]
|
74 | 1.23M | const auto amount = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-10, 50 * COIN + 10); |
75 | 1.23M | const auto script_pk = p2wsh_op_true ? Branch (75:32): [True: 977k, False: 254k]
|
76 | 977k | P2WSH_OP_TRUE : |
77 | 1.23M | ConsumeScript(fuzzed_data_provider, /*maybe_p2wsh=*/true); |
78 | 1.23M | tx_mut.vout.emplace_back(amount, script_pk); |
79 | 1.23M | } |
80 | 748k | return tx_mut; |
81 | 748k | } |
82 | | |
83 | | CScriptWitness ConsumeScriptWitness(FuzzedDataProvider& fuzzed_data_provider, const size_t max_stack_elem_size) noexcept |
84 | 239k | { |
85 | 239k | CScriptWitness ret; |
86 | 239k | const auto n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_stack_elem_size); |
87 | 618k | for (size_t i = 0; i < n_elements; ++i) { Branch (87:24): [True: 379k, False: 239k]
|
88 | 379k | ret.stack.push_back(ConsumeRandomLengthByteVector(fuzzed_data_provider)); |
89 | 379k | } |
90 | 239k | return ret; |
91 | 239k | } |
92 | | |
93 | | CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const bool maybe_p2wsh) noexcept |
94 | 1.37M | { |
95 | 1.37M | CScript r_script{}; |
96 | 1.37M | { |
97 | | // Keep a buffer of bytes to allow the fuzz engine to produce smaller |
98 | | // inputs to generate CScripts with repeated data. |
99 | 1.37M | static constexpr unsigned MAX_BUFFER_SZ{128}; |
100 | 1.37M | std::vector<uint8_t> buffer(MAX_BUFFER_SZ, uint8_t{'a'}); |
101 | 40.4M | while (fuzzed_data_provider.ConsumeBool()) { Branch (101:16): [True: 39.0M, False: 1.37M]
|
102 | 39.0M | CallOneOf( |
103 | 39.0M | fuzzed_data_provider, |
104 | 39.0M | [&] { |
105 | | // Insert byte vector directly to allow malformed or unparsable scripts |
106 | 9.12M | r_script.insert(r_script.end(), buffer.begin(), buffer.begin() + fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BUFFER_SZ)); |
107 | 9.12M | }, |
108 | 39.0M | [&] { |
109 | | // Push a byte vector from the buffer |
110 | 27.1M | r_script << std::vector<uint8_t>{buffer.begin(), buffer.begin() + fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BUFFER_SZ)}; |
111 | 27.1M | }, |
112 | 39.0M | [&] { |
113 | | // Push multisig |
114 | | // There is a special case for this to aid the fuzz engine |
115 | | // navigate the highly structured multisig format. |
116 | 397k | r_script << fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 22); |
117 | 397k | int num_data{fuzzed_data_provider.ConsumeIntegralInRange(1, 22)}; |
118 | 4.12M | while (num_data--) { Branch (118:28): [True: 3.72M, False: 397k]
|
119 | 3.72M | auto pubkey_bytes{ConstructPubKeyBytes(fuzzed_data_provider, buffer, fuzzed_data_provider.ConsumeBool())}; |
120 | 3.72M | if (fuzzed_data_provider.ConsumeBool()) { Branch (120:29): [True: 3.19M, False: 529k]
|
121 | 3.19M | pubkey_bytes.back() = num_data; // Make each pubkey different |
122 | 3.19M | } |
123 | 3.72M | r_script << pubkey_bytes; |
124 | 3.72M | } |
125 | 397k | r_script << fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 22); |
126 | 397k | }, |
127 | 39.0M | [&] { |
128 | | // Mutate the buffer |
129 | 307k | const auto vec{ConsumeRandomLengthByteVector(fuzzed_data_provider, /*max_length=*/MAX_BUFFER_SZ)}; |
130 | 307k | std::copy(vec.begin(), vec.end(), buffer.begin()); |
131 | 307k | }, |
132 | 39.0M | [&] { |
133 | | // Push an integral |
134 | 557k | r_script << fuzzed_data_provider.ConsumeIntegral<int64_t>(); |
135 | 557k | }, |
136 | 39.0M | [&] { |
137 | | // Push an opcode |
138 | 1.02M | r_script << ConsumeOpcodeType(fuzzed_data_provider); |
139 | 1.02M | }, |
140 | 39.0M | [&] { |
141 | | // Push a scriptnum |
142 | 488k | r_script << ConsumeScriptNum(fuzzed_data_provider); |
143 | 488k | }); |
144 | 39.0M | } |
145 | 1.37M | } |
146 | 1.37M | if (maybe_p2wsh && fuzzed_data_provider.ConsumeBool()) { Branch (146:9): [True: 254k, False: 1.12M]
Branch (146:24): [True: 118k, False: 135k]
|
147 | 118k | uint256 script_hash; |
148 | 118k | CSHA256().Write(r_script.data(), r_script.size()).Finalize(script_hash.begin()); |
149 | 118k | r_script.clear(); |
150 | 118k | r_script << OP_0 << ToByteVector(script_hash); |
151 | 118k | } |
152 | 1.37M | return r_script; |
153 | 1.37M | } |
154 | | |
155 | | uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept |
156 | 20.2M | { |
157 | 20.2M | return fuzzed_data_provider.ConsumeBool() ? Branch (157:12): [True: 9.86M, False: 10.4M]
|
158 | 9.86M | fuzzed_data_provider.PickValueInArray({ |
159 | 9.86M | CTxIn::SEQUENCE_FINAL, |
160 | 9.86M | CTxIn::MAX_SEQUENCE_NONFINAL, |
161 | 9.86M | MAX_BIP125_RBF_SEQUENCE, |
162 | 9.86M | }) : |
163 | 20.2M | fuzzed_data_provider.ConsumeIntegral<uint32_t>(); |
164 | 20.2M | } |
165 | | |
166 | | std::map<COutPoint, Coin> ConsumeCoins(FuzzedDataProvider& fuzzed_data_provider) noexcept |
167 | 12.8k | { |
168 | 12.8k | std::map<COutPoint, Coin> coins; |
169 | 42.0k | LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 10000) { |
170 | 42.0k | const std::optional<COutPoint> outpoint{ConsumeDeserializable<COutPoint>(fuzzed_data_provider)}; |
171 | 42.0k | if (!outpoint) { Branch (171:13): [True: 1.87k, False: 40.1k]
|
172 | 1.87k | break; |
173 | 1.87k | } |
174 | 40.1k | const std::optional<Coin> coin{ConsumeDeserializable<Coin>(fuzzed_data_provider)}; |
175 | 40.1k | if (!coin) { Branch (175:13): [True: 1.05k, False: 39.0k]
|
176 | 1.05k | break; |
177 | 1.05k | } |
178 | 39.0k | coins[*outpoint] = *coin; |
179 | 39.0k | } |
180 | | |
181 | 12.8k | return coins; |
182 | 12.8k | } |
183 | | |
184 | | CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept |
185 | 24.1k | { |
186 | 24.1k | CTxDestination tx_destination; |
187 | 24.1k | const size_t call_size{CallOneOf( |
188 | 24.1k | fuzzed_data_provider, |
189 | 24.1k | [&] { |
190 | 7.69k | tx_destination = CNoDestination{}; |
191 | 7.69k | }, |
192 | 24.1k | [&] { |
193 | 2.87k | bool compressed = fuzzed_data_provider.ConsumeBool(); |
194 | 2.87k | CPubKey pk{ConstructPubKeyBytes( |
195 | 2.87k | fuzzed_data_provider, |
196 | 2.87k | ConsumeFixedLengthByteVector(fuzzed_data_provider, (compressed ? CPubKey::COMPRESSED_SIZE : CPubKey::SIZE)), Branch (196:73): [True: 1.26k, False: 1.61k]
|
197 | 2.87k | compressed |
198 | 2.87k | )}; |
199 | 2.87k | tx_destination = PubKeyDestination{pk}; |
200 | 2.87k | }, |
201 | 24.1k | [&] { |
202 | 1.06k | tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)}; |
203 | 1.06k | }, |
204 | 24.1k | [&] { |
205 | 1.12k | tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)}; |
206 | 1.12k | }, |
207 | 24.1k | [&] { |
208 | 1.08k | tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)}; |
209 | 1.08k | }, |
210 | 24.1k | [&] { |
211 | 929 | tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)}; |
212 | 929 | }, |
213 | 24.1k | [&] { |
214 | 3.63k | tx_destination = WitnessV1Taproot{XOnlyPubKey{ConsumeUInt256(fuzzed_data_provider)}}; |
215 | 3.63k | }, |
216 | 24.1k | [&] { |
217 | 1.11k | tx_destination = PayToAnchor{}; |
218 | 1.11k | }, |
219 | 24.1k | [&] { |
220 | 4.61k | std::vector<unsigned char> program{ConsumeRandomLengthByteVector(fuzzed_data_provider, /*max_length=*/40)}; |
221 | 4.61k | if (program.size() < 2) { Branch (221:17): [True: 1.63k, False: 2.97k]
|
222 | 1.63k | program = {0, 0}; |
223 | 1.63k | } |
224 | 4.61k | tx_destination = WitnessUnknown{fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(2, 16), program}; |
225 | 4.61k | })}; |
226 | 24.1k | Assert(call_size == std::variant_size_v<CTxDestination>); |
227 | 24.1k | return tx_destination; |
228 | 24.1k | } |
229 | | |
230 | | CKey ConsumePrivateKey(FuzzedDataProvider& fuzzed_data_provider, std::optional<bool> compressed) noexcept |
231 | 51.8k | { |
232 | 51.8k | auto key_data = fuzzed_data_provider.ConsumeBytes<uint8_t>(32); |
233 | 51.8k | key_data.resize(32); |
234 | 51.8k | CKey key; |
235 | 51.8k | bool compressed_value = compressed ? *compressed : fuzzed_data_provider.ConsumeBool(); Branch (235:29): [True: 21.0k, False: 30.8k]
|
236 | 51.8k | key.Set(key_data.begin(), key_data.end(), compressed_value); |
237 | 51.8k | return key; |
238 | 51.8k | } |
239 | | |
240 | | bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept |
241 | 4.28k | { |
242 | 11.6k | for (const CTxIn& tx_in : tx.vin) { Branch (242:29): [True: 11.6k, False: 4.02k]
|
243 | 11.6k | const Coin& coin = inputs.AccessCoin(tx_in.prevout); |
244 | 11.6k | if (coin.IsSpent()) { Branch (244:13): [True: 259, False: 11.3k]
|
245 | 259 | return true; |
246 | 259 | } |
247 | 11.6k | } |
248 | 4.02k | return false; |
249 | 4.28k | } |
250 | | |
251 | | FILE* FuzzedFileProvider::open() |
252 | 7.61k | { |
253 | 7.61k | SetFuzzedErrNo(m_fuzzed_data_provider); |
254 | 7.61k | if (m_fuzzed_data_provider.ConsumeBool()) { Branch (254:9): [True: 221, False: 7.39k]
|
255 | 221 | return nullptr; |
256 | 221 | } |
257 | 7.39k | std::string mode; |
258 | 7.39k | CallOneOf( |
259 | 7.39k | m_fuzzed_data_provider, |
260 | 7.39k | [&] { |
261 | 5.65k | mode = "r"; |
262 | 5.65k | }, |
263 | 7.39k | [&] { |
264 | 627 | mode = "r+"; |
265 | 627 | }, |
266 | 7.39k | [&] { |
267 | 128 | mode = "w"; |
268 | 128 | }, |
269 | 7.39k | [&] { |
270 | 561 | mode = "w+"; |
271 | 561 | }, |
272 | 7.39k | [&] { |
273 | 83 | mode = "a"; |
274 | 83 | }, |
275 | 7.39k | [&] { |
276 | 342 | mode = "a+"; |
277 | 342 | }); |
278 | 7.39k | #if defined _GNU_SOURCE && (defined(__linux__) || defined(__FreeBSD__)) |
279 | 7.39k | const cookie_io_functions_t io_hooks = { |
280 | 7.39k | FuzzedFileProvider::read, |
281 | 7.39k | FuzzedFileProvider::write, |
282 | 7.39k | FuzzedFileProvider::seek, |
283 | 7.39k | FuzzedFileProvider::close, |
284 | 7.39k | }; |
285 | 7.39k | return fopencookie(this, mode.c_str(), io_hooks); |
286 | | #else |
287 | | (void)mode; |
288 | | return nullptr; |
289 | | #endif |
290 | 7.61k | } |
291 | | |
292 | | ssize_t FuzzedFileProvider::read(void* cookie, char* buf, size_t size) |
293 | 46.9k | { |
294 | 46.9k | FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie; |
295 | 46.9k | SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider); |
296 | 46.9k | if (buf == nullptr || size == 0 || fuzzed_file->m_fuzzed_data_provider.ConsumeBool()) { Branch (296:9): [True: 0, False: 46.9k]
Branch (296:27): [True: 0, False: 46.9k]
Branch (296:40): [True: 8.72k, False: 38.2k]
|
297 | 8.72k | return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1; Branch (297:16): [True: 215, False: 8.50k]
|
298 | 8.72k | } |
299 | 38.2k | const std::vector<uint8_t> random_bytes = fuzzed_file->m_fuzzed_data_provider.ConsumeBytes<uint8_t>(size); |
300 | 38.2k | if (random_bytes.empty()) { Branch (300:9): [True: 3.48k, False: 34.7k]
|
301 | 3.48k | return 0; |
302 | 3.48k | } |
303 | 34.7k | std::memcpy(buf, random_bytes.data(), random_bytes.size()); |
304 | 34.7k | if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)random_bytes.size())) { Branch (304:9): [True: 0, False: 34.7k]
|
305 | 0 | return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1; Branch (305:16): [True: 0, False: 0]
|
306 | 0 | } |
307 | 34.7k | fuzzed_file->m_offset += random_bytes.size(); |
308 | 34.7k | return random_bytes.size(); |
309 | 34.7k | } |
310 | | |
311 | | ssize_t FuzzedFileProvider::write(void* cookie, const char* buf, size_t size) |
312 | 2.19k | { |
313 | 2.19k | FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie; |
314 | 2.19k | SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider); |
315 | 2.19k | const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size); |
316 | 2.19k | if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) { Branch (316:9): [True: 0, False: 2.19k]
|
317 | 0 | return 0; |
318 | 0 | } |
319 | 2.19k | fuzzed_file->m_offset += n; |
320 | 2.19k | return n; |
321 | 2.19k | } |
322 | | |
323 | | int FuzzedFileProvider::seek(void* cookie, int64_t* offset, int whence) |
324 | 8.03k | { |
325 | 8.03k | assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END); Branch (325:5): [True: 0, False: 8.03k]
Branch (325:5): [True: 8.03k, False: 0]
Branch (325:5): [True: 0, False: 0]
Branch (325:5): [True: 8.03k, False: 0]
|
326 | 8.03k | FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie; |
327 | 8.03k | SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider); |
328 | 8.03k | int64_t new_offset = 0; |
329 | 8.03k | if (whence == SEEK_SET) { Branch (329:9): [True: 0, False: 8.03k]
|
330 | 0 | new_offset = *offset; |
331 | 8.03k | } else if (whence == SEEK_CUR) { Branch (331:16): [True: 8.03k, False: 0]
|
332 | 8.03k | if (AdditionOverflow(fuzzed_file->m_offset, *offset)) { Branch (332:13): [True: 0, False: 8.03k]
|
333 | 0 | return -1; |
334 | 0 | } |
335 | 8.03k | new_offset = fuzzed_file->m_offset + *offset; |
336 | 8.03k | } else if (whence == SEEK_END) { Branch (336:16): [True: 0, False: 0]
|
337 | 0 | const int64_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 4096); |
338 | 0 | if (AdditionOverflow(n, *offset)) { Branch (338:13): [True: 0, False: 0]
|
339 | 0 | return -1; |
340 | 0 | } |
341 | 0 | new_offset = n + *offset; |
342 | 0 | } |
343 | 8.03k | if (new_offset < 0) { Branch (343:9): [True: 231, False: 7.80k]
|
344 | 231 | return -1; |
345 | 231 | } |
346 | 7.80k | fuzzed_file->m_offset = new_offset; |
347 | 7.80k | *offset = new_offset; |
348 | 7.80k | return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0); |
349 | 8.03k | } |
350 | | |
351 | | int FuzzedFileProvider::close(void* cookie) |
352 | 7.39k | { |
353 | 7.39k | FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie; |
354 | 7.39k | SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider); |
355 | 7.39k | return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0); |
356 | 7.39k | } |