mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-12 04:42:36 -03:00
Merge #18736: test: Add fuzzing harnesses for various classes/functions in util/
32b6b386a5
tests: Sort fuzzing harnesses (practicalswift)e1e181fad1
tests: Add fuzzing coverage for JSONRPCTransactionError(...) and RPCErrorFromTransactionError(...) (practicalswift)103b6ecce0
tests: Add fuzzing coverage for TransactionErrorString(...) (practicalswift)dde508b8b0
tests: Add fuzzing coverage for ParseFixedPoint(...) (practicalswift)1532259fca
tests: Add fuzzing coverage for FormatHDKeypath(...) and WriteHDKeypath(...) (practicalswift)90b635e84e
tests: Add fuzzing coverage for CHECK_NONFATAL(...) (practicalswift)a4e3d13df6
tests: Add fuzzing coverage for StringForFeeReason(...) (practicalswift)a19598cf98
tests: Add fuzzing harness for functions in system.h (ArgsManager) (practicalswift) Pull request description: Add fuzzing harnesses for various classes/functions in `util/`. See [`doc/fuzzing.md`](https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.md) for information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the [Bitcoin Core fuzzing corpus repo](https://github.com/bitcoin-core/qa-assets). Happy fuzzing :) Top commit has no ACKs. Tree-SHA512: d27947220850c2a202c7740f44140c17545f45522596912452ccab0c2f5379abeb07cc769982c7855cb465059425206371a2b75ee1c285b03984161c9619d0b0
This commit is contained in:
commit
95a9165016
7 changed files with 189 additions and 5 deletions
|
@ -49,6 +49,7 @@ FUZZ_TARGETS = \
|
||||||
test/fuzz/key \
|
test/fuzz/key \
|
||||||
test/fuzz/key_io \
|
test/fuzz/key_io \
|
||||||
test/fuzz/key_origin_info_deserialize \
|
test/fuzz/key_origin_info_deserialize \
|
||||||
|
test/fuzz/kitchen_sink \
|
||||||
test/fuzz/locale \
|
test/fuzz/locale \
|
||||||
test/fuzz/merkle_block_deserialize \
|
test/fuzz/merkle_block_deserialize \
|
||||||
test/fuzz/merkleblock \
|
test/fuzz/merkleblock \
|
||||||
|
@ -64,13 +65,12 @@ FUZZ_TARGETS = \
|
||||||
test/fuzz/parse_numbers \
|
test/fuzz/parse_numbers \
|
||||||
test/fuzz/parse_script \
|
test/fuzz/parse_script \
|
||||||
test/fuzz/parse_univalue \
|
test/fuzz/parse_univalue \
|
||||||
test/fuzz/prevector \
|
|
||||||
test/fuzz/partial_merkle_tree_deserialize \
|
test/fuzz/partial_merkle_tree_deserialize \
|
||||||
test/fuzz/partially_signed_transaction_deserialize \
|
test/fuzz/partially_signed_transaction_deserialize \
|
||||||
test/fuzz/pow \
|
test/fuzz/pow \
|
||||||
test/fuzz/prefilled_transaction_deserialize \
|
test/fuzz/prefilled_transaction_deserialize \
|
||||||
|
test/fuzz/prevector \
|
||||||
test/fuzz/primitives_transaction \
|
test/fuzz/primitives_transaction \
|
||||||
test/fuzz/process_messages \
|
|
||||||
test/fuzz/process_message \
|
test/fuzz/process_message \
|
||||||
test/fuzz/process_message_addr \
|
test/fuzz/process_message_addr \
|
||||||
test/fuzz/process_message_block \
|
test/fuzz/process_message_block \
|
||||||
|
@ -96,6 +96,7 @@ FUZZ_TARGETS = \
|
||||||
test/fuzz/process_message_tx \
|
test/fuzz/process_message_tx \
|
||||||
test/fuzz/process_message_verack \
|
test/fuzz/process_message_verack \
|
||||||
test/fuzz/process_message_version \
|
test/fuzz/process_message_version \
|
||||||
|
test/fuzz/process_messages \
|
||||||
test/fuzz/protocol \
|
test/fuzz/protocol \
|
||||||
test/fuzz/psbt \
|
test/fuzz/psbt \
|
||||||
test/fuzz/psbt_input_deserialize \
|
test/fuzz/psbt_input_deserialize \
|
||||||
|
@ -116,6 +117,7 @@ FUZZ_TARGETS = \
|
||||||
test/fuzz/string \
|
test/fuzz/string \
|
||||||
test/fuzz/strprintf \
|
test/fuzz/strprintf \
|
||||||
test/fuzz/sub_net_deserialize \
|
test/fuzz/sub_net_deserialize \
|
||||||
|
test/fuzz/system \
|
||||||
test/fuzz/timedata \
|
test/fuzz/timedata \
|
||||||
test/fuzz/transaction \
|
test/fuzz/transaction \
|
||||||
test/fuzz/tx_in \
|
test/fuzz/tx_in \
|
||||||
|
@ -567,6 +569,12 @@ test_fuzz_key_origin_info_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
||||||
test_fuzz_key_origin_info_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
test_fuzz_key_origin_info_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||||
test_fuzz_key_origin_info_deserialize_SOURCES = test/fuzz/deserialize.cpp
|
test_fuzz_key_origin_info_deserialize_SOURCES = test/fuzz/deserialize.cpp
|
||||||
|
|
||||||
|
test_fuzz_kitchen_sink_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
|
test_fuzz_kitchen_sink_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
test_fuzz_kitchen_sink_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
||||||
|
test_fuzz_kitchen_sink_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||||
|
test_fuzz_kitchen_sink_SOURCES = test/fuzz/kitchen_sink.cpp
|
||||||
|
|
||||||
test_fuzz_locale_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
test_fuzz_locale_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
test_fuzz_locale_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
test_fuzz_locale_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
test_fuzz_locale_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
test_fuzz_locale_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
||||||
|
@ -969,6 +977,12 @@ test_fuzz_sub_net_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
||||||
test_fuzz_sub_net_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
test_fuzz_sub_net_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||||
test_fuzz_sub_net_deserialize_SOURCES = test/fuzz/deserialize.cpp
|
test_fuzz_sub_net_deserialize_SOURCES = test/fuzz/deserialize.cpp
|
||||||
|
|
||||||
|
test_fuzz_system_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
|
test_fuzz_system_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
test_fuzz_system_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
||||||
|
test_fuzz_system_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||||
|
test_fuzz_system_SOURCES = test/fuzz/system.cpp
|
||||||
|
|
||||||
test_fuzz_timedata_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
test_fuzz_timedata_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
test_fuzz_timedata_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
test_fuzz_timedata_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
test_fuzz_timedata_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
test_fuzz_timedata_LDADD = $(FUZZ_SUITE_LD_COMMON)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
|
#include <util/fees.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -23,4 +24,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
||||||
const CAmount rounded_fee = fee_filter_rounder.round(current_minimum_fee);
|
const CAmount rounded_fee = fee_filter_rounder.round(current_minimum_fee);
|
||||||
assert(MoneyRange(rounded_fee));
|
assert(MoneyRange(rounded_fee));
|
||||||
}
|
}
|
||||||
|
const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED});
|
||||||
|
(void)StringForFeeReason(fee_reason);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <time.h>
|
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
#include <util/check.h>
|
||||||
#include <util/moneystr.h>
|
#include <util/moneystr.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <ctime>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -287,8 +288,12 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
||||||
try {
|
try {
|
||||||
const uint64_t deserialized_u64 = ReadCompactSize(stream);
|
const uint64_t deserialized_u64 = ReadCompactSize(stream);
|
||||||
assert(u64 == deserialized_u64 && stream.empty());
|
assert(u64 == deserialized_u64 && stream.empty());
|
||||||
}
|
} catch (const std::ios_base::failure&) {
|
||||||
catch (const std::ios_base::failure&) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
CHECK_NONFATAL(b);
|
||||||
|
} catch (const NonFatalCheckError&) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
25
src/test/fuzz/kitchen_sink.cpp
Normal file
25
src/test/fuzz/kitchen_sink.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) 2020 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <rpc/util.h>
|
||||||
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
|
#include <test/fuzz/fuzz.h>
|
||||||
|
#include <test/fuzz/util.h>
|
||||||
|
#include <util/error.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// The fuzzing kitchen sink: Fuzzing harness for functions that need to be
|
||||||
|
// fuzzed but a.) don't belong in any existing fuzzing harness file, and
|
||||||
|
// b.) are not important enough to warrant their own fuzzing harness file.
|
||||||
|
void test_one_input(const std::vector<uint8_t>& buffer)
|
||||||
|
{
|
||||||
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
|
const TransactionError transaction_error = fuzzed_data_provider.PickValueInArray<TransactionError>({TransactionError::OK, TransactionError::MISSING_INPUTS, TransactionError::ALREADY_IN_CHAIN, TransactionError::P2P_DISABLED, TransactionError::MEMPOOL_REJECTED, TransactionError::MEMPOOL_ERROR, TransactionError::INVALID_PSBT, TransactionError::PSBT_MISMATCH, TransactionError::SIGHASH_MISMATCH, TransactionError::MAX_FEE_EXCEEDED});
|
||||||
|
(void)JSONRPCTransactionError(transaction_error);
|
||||||
|
(void)RPCErrorFromTransactionError(transaction_error);
|
||||||
|
(void)TransactionErrorString(transaction_error);
|
||||||
|
}
|
|
@ -2,12 +2,22 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
|
#include <test/fuzz/util.h>
|
||||||
#include <util/bip32.h>
|
#include <util/bip32.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
void test_one_input(const std::vector<uint8_t>& buffer)
|
void test_one_input(const std::vector<uint8_t>& buffer)
|
||||||
{
|
{
|
||||||
const std::string keypath_str(buffer.begin(), buffer.end());
|
const std::string keypath_str(buffer.begin(), buffer.end());
|
||||||
std::vector<uint32_t> keypath;
|
std::vector<uint32_t> keypath;
|
||||||
(void)ParseHDKeypath(keypath_str, keypath);
|
(void)ParseHDKeypath(keypath_str, keypath);
|
||||||
|
|
||||||
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
const std::vector<uint32_t> random_keypath = ConsumeRandomLengthIntegralVector<uint32_t>(fuzzed_data_provider);
|
||||||
|
(void)FormatHDKeypath(random_keypath);
|
||||||
|
(void)WriteHDKeypath(random_keypath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,4 +115,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
||||||
assert(data_stream.empty());
|
assert(data_stream.empty());
|
||||||
assert(deserialized_string == random_string_1);
|
assert(deserialized_string == random_string_1);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
int64_t amount_out;
|
||||||
|
(void)ParseFixedPoint(random_string_1, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1024), &amount_out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
123
src/test/fuzz/system.cpp
Normal file
123
src/test/fuzz/system.cpp
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// Copyright (c) 2020 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
|
#include <test/fuzz/fuzz.h>
|
||||||
|
#include <test/fuzz/util.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::string GetArgumentName(const std::string& name)
|
||||||
|
{
|
||||||
|
size_t idx = name.find('=');
|
||||||
|
if (idx == std::string::npos) {
|
||||||
|
idx = name.size();
|
||||||
|
}
|
||||||
|
return name.substr(0, idx);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void test_one_input(const std::vector<uint8_t>& buffer)
|
||||||
|
{
|
||||||
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
ArgsManager args_manager{};
|
||||||
|
|
||||||
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
|
SetupHelpOptions(args_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fuzzed_data_provider.ConsumeBool()) {
|
||||||
|
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 7)) {
|
||||||
|
case 0: {
|
||||||
|
args_manager.SelectConfigNetwork(fuzzed_data_provider.ConsumeRandomLengthString(16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
args_manager.SoftSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
args_manager.ForceSetArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeRandomLengthString(16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
args_manager.SoftSetBoolArg(fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeBool());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
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::HIDDEN});
|
||||||
|
// Avoid hitting:
|
||||||
|
// util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
|
||||||
|
const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16));
|
||||||
|
if (args_manager.GetArgFlags(argument_name) != nullopt) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
args_manager.AddArg(argument_name, fuzzed_data_provider.ConsumeRandomLengthString(16), fuzzed_data_provider.ConsumeIntegral<unsigned int>(), options_category);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
// Avoid hitting:
|
||||||
|
// util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed.
|
||||||
|
const std::vector<std::string> names = ConsumeRandomLengthStringVector(fuzzed_data_provider);
|
||||||
|
std::vector<std::string> hidden_arguments;
|
||||||
|
for (const std::string& name : names) {
|
||||||
|
const std::string hidden_argument = GetArgumentName(name);
|
||||||
|
if (args_manager.GetArgFlags(hidden_argument) != nullopt) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (std::find(hidden_arguments.begin(), hidden_arguments.end(), hidden_argument) != hidden_arguments.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
hidden_arguments.push_back(hidden_argument);
|
||||||
|
}
|
||||||
|
args_manager.AddHiddenArgs(hidden_arguments);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
args_manager.ClearArgs();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7: {
|
||||||
|
const std::vector<std::string> random_arguments = ConsumeRandomLengthStringVector(fuzzed_data_provider);
|
||||||
|
std::vector<const char*> argv;
|
||||||
|
argv.resize(random_arguments.size());
|
||||||
|
for (const std::string& random_argument : random_arguments) {
|
||||||
|
argv.push_back(random_argument.c_str());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
std::string error;
|
||||||
|
(void)args_manager.ParseParameters(argv.size(), argv.data(), error);
|
||||||
|
} catch (const std::logic_error&) {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string s1 = fuzzed_data_provider.ConsumeRandomLengthString(16);
|
||||||
|
const std::string s2 = fuzzed_data_provider.ConsumeRandomLengthString(16);
|
||||||
|
const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
|
||||||
|
const bool b = fuzzed_data_provider.ConsumeBool();
|
||||||
|
|
||||||
|
(void)args_manager.GetArg(s1, i64);
|
||||||
|
(void)args_manager.GetArg(s1, s2);
|
||||||
|
(void)args_manager.GetArgFlags(s1);
|
||||||
|
(void)args_manager.GetArgs(s1);
|
||||||
|
(void)args_manager.GetBoolArg(s1, b);
|
||||||
|
try {
|
||||||
|
(void)args_manager.GetChainName();
|
||||||
|
} catch (const std::runtime_error&) {
|
||||||
|
}
|
||||||
|
(void)args_manager.GetHelpMessage();
|
||||||
|
(void)args_manager.GetUnrecognizedSections();
|
||||||
|
(void)args_manager.GetUnsuitableSectionOnlyArgs();
|
||||||
|
(void)args_manager.IsArgNegated(s1);
|
||||||
|
(void)args_manager.IsArgSet(s1);
|
||||||
|
|
||||||
|
(void)HelpRequested(args_manager);
|
||||||
|
}
|
Loading…
Reference in a new issue