Branch data Line data Source code
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 <set>
13 : : #include <string>
14 : : #include <vector>
15 : :
16 : : namespace {
17 : 1 : void initialize_system()
18 : : {
19 [ + - + - : 2 : static const auto testing_setup = MakeNoLogFileContext<>();
+ - ]
20 : 1 : }
21 : :
22 : 94443 : std::string GetArgumentName(const std::string& name)
23 : : {
24 : 94443 : size_t idx = name.find('=');
25 [ + + ]: 94443 : if (idx == std::string::npos) {
26 [ - + ]: 85820 : idx = name.size();
27 : : }
28 : 94443 : return name.substr(0, idx);
29 : : }
30 : :
31 [ + - ]: 1530 : FUZZ_TARGET(system, .init = initialize_system)
32 : : {
33 : 1056 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
34 : 1056 : ArgsManager args_manager{};
35 : 1056 : std::vector<std::string> command_option_names;
36 : :
37 [ + + ]: 1056 : if (fuzzed_data_provider.ConsumeBool()) {
38 [ + - ]: 838 : SetupHelpOptions(args_manager);
39 : : }
40 : :
41 [ + + + + ]: 278158 : LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 3000) {
42 [ + - ]: 277102 : CallOneOf(
43 : : fuzzed_data_provider,
44 : 78577 : [&] {
45 [ + - ]: 78577 : args_manager.SelectConfigNetwork(fuzzed_data_provider.ConsumeRandomLengthString(16));
46 : 78577 : },
47 : 17657 : [&] {
48 : 17657 : auto str_arg = fuzzed_data_provider.ConsumeRandomLengthString(16);
49 [ + - ]: 17657 : auto str_value = fuzzed_data_provider.ConsumeRandomLengthString(16);
50 [ + - ]: 17657 : args_manager.SoftSetArg(str_arg, str_value);
51 : 17657 : },
52 : 13571 : [&] {
53 : 13571 : auto str_arg = fuzzed_data_provider.ConsumeRandomLengthString(16);
54 [ + - ]: 13571 : auto str_value = fuzzed_data_provider.ConsumeRandomLengthString(16);
55 [ + - ]: 13571 : args_manager.ForceSetArg(str_arg, str_value);
56 : 13571 : },
57 : 29415 : [&] {
58 : 29415 : auto str_arg = fuzzed_data_provider.ConsumeRandomLengthString(16);
59 : 29415 : auto f_value = fuzzed_data_provider.ConsumeBool();
60 [ + - ]: 29415 : args_manager.SoftSetBoolArg(str_arg, f_value);
61 : 29415 : },
62 : 23102 : [&] {
63 : 23102 : 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::COMMAND_OPTIONS, OptionsCategory::HIDDEN});
64 : : // Avoid hitting:
65 : : // common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
66 [ + - ]: 23102 : const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16));
67 [ + - + + ]: 23102 : if (args_manager.GetArgFlags(argument_name) != std::nullopt) {
68 : 13492 : return;
69 : : }
70 [ + - ]: 9610 : auto help = fuzzed_data_provider.ConsumeRandomLengthString(16);
71 : 9610 : auto flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>() & ~ArgsManager::COMMAND;
72 [ + - ]: 9610 : args_manager.AddArg(argument_name, help, flags, options_category);
73 [ + + ]: 9610 : if (options_category == OptionsCategory::COMMAND_OPTIONS) {
74 [ + - ]: 2884 : command_option_names.push_back(argument_name);
75 : : }
76 : 23102 : },
77 : 31551 : [&] {
78 : 31551 : auto cmd = fuzzed_data_provider.ConsumeRandomLengthString(16);
79 [ + + + + : 31551 : if (cmd.empty() || cmd[0] == '-' || cmd.find('=') != std::string::npos) return;
+ + ]
80 [ + - + + ]: 19062 : if (args_manager.GetArgFlags(cmd) != std::nullopt) return;
81 [ + - ]: 13762 : auto help = fuzzed_data_provider.ConsumeRandomLengthString(16);
82 : 13762 : std::set<std::string> options;
83 [ + + ]: 39993 : for (const auto& opt : command_option_names) {
84 [ + + ]: 26231 : if (fuzzed_data_provider.ConsumeBool()) {
85 [ + - ]: 25631 : options.insert(opt);
86 : : }
87 : : }
88 [ + - ]: 27524 : args_manager.AddCommand(cmd, help, std::move(options));
89 : 31551 : },
90 : 27785 : [&] {
91 : : // Avoid hitting:
92 : : // common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
93 : 27785 : const std::vector<std::string> names = ConsumeRandomLengthStringVector(fuzzed_data_provider);
94 : 27785 : std::vector<std::string> hidden_arguments;
95 [ + + ]: 99126 : for (const std::string& name : names) {
96 [ + - ]: 71341 : const std::string hidden_argument = GetArgumentName(name);
97 [ + - + + ]: 71341 : if (args_manager.GetArgFlags(hidden_argument) != std::nullopt) {
98 : 52760 : continue;
99 : : }
100 [ + + ]: 18581 : if (std::find(hidden_arguments.begin(), hidden_arguments.end(), hidden_argument) != hidden_arguments.end()) {
101 : 1311 : continue;
102 : : }
103 [ + - ]: 17270 : hidden_arguments.push_back(hidden_argument);
104 : 71341 : }
105 [ + - ]: 27785 : args_manager.AddHiddenArgs(hidden_arguments);
106 : 27785 : },
107 : 5564 : [&] {
108 : 5564 : args_manager.ClearArgs();
109 : 5564 : command_option_names.clear();
110 : 5564 : },
111 : 49880 : [&] {
112 : 49880 : const std::vector<std::string> random_arguments = ConsumeRandomLengthStringVector(fuzzed_data_provider);
113 : 49880 : std::vector<const char*> argv;
114 [ - + + - ]: 49880 : argv.reserve(random_arguments.size());
115 [ + + ]: 273938 : for (const std::string& random_argument : random_arguments) {
116 [ + - ]: 224058 : argv.push_back(random_argument.c_str());
117 : : }
118 : 49880 : try {
119 [ - + ]: 49880 : std::string error;
120 [ - + + - ]: 49880 : (void)args_manager.ParseParameters(argv.size(), argv.data(), error);
121 [ - - ]: 49880 : } catch (const std::logic_error&) {
122 : 0 : }
123 : 49880 : });
124 : : }
125 : :
126 [ + - ]: 1056 : const std::string s1 = fuzzed_data_provider.ConsumeRandomLengthString(16);
127 [ + - ]: 1056 : const std::string s2 = fuzzed_data_provider.ConsumeRandomLengthString(16);
128 : 1056 : const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
129 : 1056 : const bool b = fuzzed_data_provider.ConsumeBool();
130 : :
131 [ + - ]: 1056 : (void)args_manager.GetIntArg(s1, i64);
132 [ + - ]: 1056 : (void)args_manager.GetArg(s1, s2);
133 [ + - ]: 1056 : (void)args_manager.GetArgFlags(s1);
134 [ + - ]: 1056 : (void)args_manager.GetArgs(s1);
135 [ + - ]: 1056 : (void)args_manager.GetBoolArg(s1, b);
136 : 1056 : try {
137 [ + + ]: 2102 : (void)args_manager.GetChainTypeString();
138 [ - + ]: 10 : } catch (const std::runtime_error&) {
139 : 10 : }
140 [ + - ]: 1056 : (void)args_manager.GetHelpMessage();
141 [ + - ]: 1056 : const auto command = args_manager.GetCommand();
142 [ + + ]: 1056 : if (command) {
143 [ + - ]: 358 : (void)args_manager.CheckCommandOptions(command->command);
144 : : }
145 [ + - ]: 1056 : (void)args_manager.GetUnrecognizedSections();
146 [ + - ]: 1056 : (void)args_manager.GetUnsuitableSectionOnlyArgs();
147 [ + - ]: 1056 : (void)args_manager.IsArgNegated(s1);
148 [ + - ]: 1056 : (void)args_manager.IsArgSet(s1);
149 : :
150 [ + - ]: 1056 : (void)HelpRequested(args_manager);
151 : 1056 : }
152 : : } // namespace
|