/ src / test / fuzz / system.cpp
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