3
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
4
5
5
#include < base58.h>
6
- #include < core_io.h>
7
6
#include < key.h>
8
7
#include < key_io.h>
9
- #include < node/context.h>
10
8
#include < primitives/block.h>
11
9
#include < primitives/transaction.h>
12
10
#include < psbt.h>
13
- #include < rpc/blockchain.h>
14
11
#include < rpc/client.h>
15
12
#include < rpc/request.h>
16
13
#include < rpc/server.h>
17
- #include < rpc/util.h>
18
14
#include < span.h>
19
15
#include < streams.h>
20
16
#include < test/fuzz/FuzzedDataProvider.h>
21
17
#include < test/fuzz/fuzz.h>
22
18
#include < test/fuzz/util.h>
23
19
#include < test/util/setup_common.h>
24
20
#include < tinyformat.h>
21
+ #include < uint256.h>
25
22
#include < univalue.h>
26
- #include < util/chaintype.h>
27
23
#include < util/strencodings.h>
28
24
#include < util/string.h>
29
25
#include < util/time.h>
30
26
27
+ #include < algorithm>
28
+ #include < cassert>
31
29
#include < cstdint>
30
+ #include < cstdlib>
31
+ #include < exception>
32
32
#include < iostream>
33
33
#include < memory>
34
34
#include < optional>
35
35
#include < stdexcept>
36
- #include < string>
37
36
#include < vector>
37
+ enum class ChainType ;
38
38
39
39
namespace {
40
40
struct RPCFuzzTestingSetup : public TestingSetup {
@@ -184,7 +184,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
184
184
" waitfornewblock" ,
185
185
};
186
186
187
- std::string ConsumeScalarRPCArgument (FuzzedDataProvider& fuzzed_data_provider)
187
+ std::string ConsumeScalarRPCArgument (FuzzedDataProvider& fuzzed_data_provider, bool & good_data )
188
188
{
189
189
const size_t max_string_length = 4096 ;
190
190
const size_t max_base58_bytes_length{64 };
@@ -251,6 +251,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
251
251
// hex encoded block
252
252
std::optional<CBlock> opt_block = ConsumeDeserializable<CBlock>(fuzzed_data_provider);
253
253
if (!opt_block) {
254
+ good_data = false ;
254
255
return ;
255
256
}
256
257
CDataStream data_stream{SER_NETWORK, PROTOCOL_VERSION};
@@ -261,6 +262,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
261
262
// hex encoded block header
262
263
std::optional<CBlockHeader> opt_block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);
263
264
if (!opt_block_header) {
265
+ good_data = false ;
264
266
return ;
265
267
}
266
268
DataStream data_stream{};
@@ -271,6 +273,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
271
273
// hex encoded tx
272
274
std::optional<CMutableTransaction> opt_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
273
275
if (!opt_tx) {
276
+ good_data = false ;
274
277
return ;
275
278
}
276
279
CDataStream data_stream{SER_NETWORK, fuzzed_data_provider.ConsumeBool () ? PROTOCOL_VERSION : (PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)};
@@ -281,6 +284,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
281
284
// base64 encoded psbt
282
285
std::optional<PartiallySignedTransaction> opt_psbt = ConsumeDeserializable<PartiallySignedTransaction>(fuzzed_data_provider);
283
286
if (!opt_psbt) {
287
+ good_data = false ;
284
288
return ;
285
289
}
286
290
CDataStream data_stream{SER_NETWORK, PROTOCOL_VERSION};
@@ -291,6 +295,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
291
295
// base58 encoded key
292
296
CKey key = ConsumePrivateKey (fuzzed_data_provider);
293
297
if (!key.IsValid ()) {
298
+ good_data = false ;
294
299
return ;
295
300
}
296
301
r = EncodeSecret (key);
@@ -299,25 +304,27 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
299
304
// hex encoded pubkey
300
305
CKey key = ConsumePrivateKey (fuzzed_data_provider);
301
306
if (!key.IsValid ()) {
307
+ good_data = false ;
302
308
return ;
303
309
}
304
310
r = HexStr (key.GetPubKey ());
305
311
});
306
312
return r;
307
313
}
308
314
309
- std::string ConsumeArrayRPCArgument (FuzzedDataProvider& fuzzed_data_provider)
315
+ std::string ConsumeArrayRPCArgument (FuzzedDataProvider& fuzzed_data_provider, bool & good_data )
310
316
{
311
317
std::vector<std::string> scalar_arguments;
312
- LIMITED_WHILE (fuzzed_data_provider.ConsumeBool (), 100 ) {
313
- scalar_arguments.push_back (ConsumeScalarRPCArgument (fuzzed_data_provider));
318
+ LIMITED_WHILE (good_data && fuzzed_data_provider.ConsumeBool (), 100 )
319
+ {
320
+ scalar_arguments.push_back (ConsumeScalarRPCArgument (fuzzed_data_provider, good_data));
314
321
}
315
322
return " [\" " + Join (scalar_arguments, " \" ,\" " ) + " \" ]" ;
316
323
}
317
324
318
- std::string ConsumeRPCArgument (FuzzedDataProvider& fuzzed_data_provider)
325
+ std::string ConsumeRPCArgument (FuzzedDataProvider& fuzzed_data_provider, bool & good_data )
319
326
{
320
- return fuzzed_data_provider.ConsumeBool () ? ConsumeScalarRPCArgument (fuzzed_data_provider) : ConsumeArrayRPCArgument (fuzzed_data_provider);
327
+ return fuzzed_data_provider.ConsumeBool () ? ConsumeScalarRPCArgument (fuzzed_data_provider, good_data ) : ConsumeArrayRPCArgument (fuzzed_data_provider, good_data );
321
328
}
322
329
323
330
RPCFuzzTestingSetup* InitializeRPCFuzzTestingSetup ()
@@ -353,6 +360,7 @@ void initialize_rpc()
353
360
FUZZ_TARGET (rpc, .init = initialize_rpc)
354
361
{
355
362
FuzzedDataProvider fuzzed_data_provider{buffer.data (), buffer.size ()};
363
+ bool good_data{true };
356
364
SetMockTime (ConsumeTime (fuzzed_data_provider));
357
365
const std::string rpc_command = fuzzed_data_provider.ConsumeRandomLengthString (64 );
358
366
if (!g_limit_to_rpc_command.empty () && rpc_command != g_limit_to_rpc_command) {
@@ -363,8 +371,9 @@ FUZZ_TARGET(rpc, .init = initialize_rpc)
363
371
return ;
364
372
}
365
373
std::vector<std::string> arguments;
366
- LIMITED_WHILE (fuzzed_data_provider.ConsumeBool (), 100 ) {
367
- arguments.push_back (ConsumeRPCArgument (fuzzed_data_provider));
374
+ LIMITED_WHILE (good_data && fuzzed_data_provider.ConsumeBool (), 100 )
375
+ {
376
+ arguments.push_back (ConsumeRPCArgument (fuzzed_data_provider, good_data));
368
377
}
369
378
try {
370
379
rpc_testing_setup->CallRPC (rpc_command, arguments);
0 commit comments