system.cpp
1 // Copyright (c) 2020-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 <common/args.h> 6 #include <test/fuzz/FuzzedDataProvider.h> 7 #include <test/fuzz/fuzz.h> 8 #include <test/fuzz/util.h> 9 #include <test/util/setup_common.h> 10 11 #include <cstdint> 12 #include <string> 13 #include <vector> 14 15 namespace { 16 void initialize_system() 17 { 18 static const auto testing_setup = MakeNoLogFileContext<>(); 19 } 20 21 std::string GetArgumentName(const std::string& name) 22 { 23 size_t idx = name.find('='); 24 if (idx == std::string::npos) { 25 idx = name.size(); 26 } 27 return name.substr(0, idx); 28 } 29 30 FUZZ_TARGET(system, .init = initialize_system) 31 { 32 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 33 ArgsManager args_manager{}; 34 35 if (fuzzed_data_provider.ConsumeBool()) { 36 SetupHelpOptions(args_manager); 37 } 38 39 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 3000) 40 { 41 CallOneOf( 42 fuzzed_data_provider, 43 [&] { 44 args_manager.SelectConfigNetwork(fuzzed_data_provider.ConsumeRandomLengthString(16)); 45 }, 46 [&] { 47 auto str_arg = fuzzed_data_provider.ConsumeRandomLengthString(16); 48 auto str_value = fuzzed_data_provider.ConsumeRandomLengthString(16); 49 args_manager.SoftSetArg(str_arg, str_value); 50 }, 51 [&] { 52 auto str_arg = fuzzed_data_provider.ConsumeRandomLengthString(16); 53 auto str_value = fuzzed_data_provider.ConsumeRandomLengthString(16); 54 args_manager.ForceSetArg(str_arg, str_value); 55 }, 56 [&] { 57 auto str_arg = fuzzed_data_provider.ConsumeRandomLengthString(16); 58 auto f_value = fuzzed_data_provider.ConsumeBool(); 59 args_manager.SoftSetBoolArg(str_arg, f_value); 60 }, 61 [&] { 62 const OptionsCategory options_category = fuzzed_data_provider.PickValueInArray<OptionsCategory>({OptionsCategory::OPTIONS, OptionsCategory::CONNECTION, OptionsCategory::WALLET, OptionsCategory::WALLET_DEBUG_TEST, OptionsCategory::ZMQ, OptionsCategory::DEBUG_TEST, OptionsCategory::CHAINPARAMS, OptionsCategory::NODE_RELAY, OptionsCategory::BLOCK_CREATION, OptionsCategory::RPC, OptionsCategory::GUI, OptionsCategory::COMMANDS, OptionsCategory::REGISTER_COMMANDS, OptionsCategory::CLI_COMMANDS, OptionsCategory::IPC, OptionsCategory::HIDDEN}); 63 // Avoid hitting: 64 // common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed. 65 const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16)); 66 if (args_manager.GetArgFlags(argument_name) != std::nullopt) { 67 return; 68 } 69 auto help = fuzzed_data_provider.ConsumeRandomLengthString(16); 70 auto flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>() & ~ArgsManager::COMMAND; 71 args_manager.AddArg(argument_name, help, flags, options_category); 72 }, 73 [&] { 74 // Avoid hitting: 75 // common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed. 76 const std::vector<std::string> names = ConsumeRandomLengthStringVector(fuzzed_data_provider); 77 std::vector<std::string> hidden_arguments; 78 for (const std::string& name : names) { 79 const std::string hidden_argument = GetArgumentName(name); 80 if (args_manager.GetArgFlags(hidden_argument) != std::nullopt) { 81 continue; 82 } 83 if (std::find(hidden_arguments.begin(), hidden_arguments.end(), hidden_argument) != hidden_arguments.end()) { 84 continue; 85 } 86 hidden_arguments.push_back(hidden_argument); 87 } 88 args_manager.AddHiddenArgs(hidden_arguments); 89 }, 90 [&] { 91 args_manager.ClearArgs(); 92 }, 93 [&] { 94 const std::vector<std::string> random_arguments = ConsumeRandomLengthStringVector(fuzzed_data_provider); 95 std::vector<const char*> argv; 96 argv.reserve(random_arguments.size()); 97 for (const std::string& random_argument : random_arguments) { 98 argv.push_back(random_argument.c_str()); 99 } 100 try { 101 std::string error; 102 (void)args_manager.ParseParameters(argv.size(), argv.data(), error); 103 } catch (const std::logic_error&) { 104 } 105 }); 106 } 107 108 const std::string s1 = fuzzed_data_provider.ConsumeRandomLengthString(16); 109 const std::string s2 = fuzzed_data_provider.ConsumeRandomLengthString(16); 110 const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>(); 111 const bool b = fuzzed_data_provider.ConsumeBool(); 112 113 (void)args_manager.GetIntArg(s1, i64); 114 (void)args_manager.GetArg(s1, s2); 115 (void)args_manager.GetArgFlags(s1); 116 (void)args_manager.GetArgs(s1); 117 (void)args_manager.GetBoolArg(s1, b); 118 try { 119 (void)args_manager.GetChainTypeString(); 120 } catch (const std::runtime_error&) { 121 } 122 (void)args_manager.GetHelpMessage(); 123 (void)args_manager.GetUnrecognizedSections(); 124 (void)args_manager.GetUnsuitableSectionOnlyArgs(); 125 (void)args_manager.IsArgNegated(s1); 126 (void)args_manager.IsArgSet(s1); 127 128 (void)HelpRequested(args_manager); 129 } 130 } // namespace