Skip to content

add some reduction methods to the options on the fuzz tests #930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 89 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
ac9acad
add some reduction methods to the flags on the fuzz tests
phlptp Oct 7, 2023
e3b0f78
style: pre-commit.ci fixes
pre-commit-ci[bot] Oct 7, 2023
2f7bb71
add some validators to the fuzzing
phlptp Oct 8, 2023
2d9c2da
style: pre-commit.ci fixes
pre-commit-ci[bot] Oct 8, 2023
a5026d4
string range
phlptp Oct 8, 2023
ffa44bf
style: pre-commit.ci fixes
pre-commit-ci[bot] Oct 8, 2023
b758457
try config write/read on app_fuzz
phlptp Oct 8, 2023
529ff6c
style: pre-commit.ci fixes
pre-commit-ci[bot] Oct 8, 2023
3e588df
fix test for to_config in some cases
phlptp Oct 9, 2023
d6d312b
style: pre-commit.ci fixes
pre-commit-ci[bot] Oct 9, 2023
dc11854
fix more tests
phlptp Oct 9, 2023
a85f006
add fuzzing test and check
phlptp Oct 13, 2023
606f147
add fuzzing test and check
phlptp Oct 13, 2023
4c98bd8
style: pre-commit.ci fixes
pre-commit-ci[bot] Oct 28, 2023
78b97d5
fix additional fuzzing test to allow for file based array arguments o…
phlptp Nov 5, 2023
f46e903
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 5, 2023
d571f82
fix additional fail test
phlptp Nov 5, 2023
89634b3
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 5, 2023
6e700e3
remove '\0' from the list of allowed characters in a name, check name…
phlptp Nov 6, 2023
b457a85
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 6, 2023
066fb94
deal with option names in a config file that can be interpreted as se…
phlptp Nov 6, 2023
8c25086
add additional failing test
phlptp Nov 11, 2023
8c14910
Merge remote-tracking branch 'remotes/upstream/main' into fuzz_reduction
phlptp Nov 11, 2023
292d907
get fuzzing test to pass
phlptp Nov 11, 2023
a76ff99
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 11, 2023
22c7e8d
remove other control codes from valid names
phlptp Nov 11, 2023
709c5c6
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 11, 2023
c89a4c6
fix additional test case
phlptp Nov 11, 2023
a576ec7
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 11, 2023
264b0bd
add test and fix to handle '=' at the beginning of an argument name w…
phlptp Nov 12, 2023
fb75765
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 12, 2023
f28d3be
fix fail condition with ' in binary string
phlptp Nov 12, 2023
0880673
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 12, 2023
ac3b887
add literal comment modifier in the config file parsing
phlptp Nov 23, 2023
2a83631
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 23, 2023
56897b9
add fuzz test
phlptp Nov 23, 2023
03b0c07
fix another fuzzing issue
phlptp Nov 23, 2023
7f7bb45
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 23, 2023
4bd1a27
more fuzz tests and fixes
phlptp Nov 23, 2023
6371981
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 23, 2023
fc83edb
handle string escape conversion
phlptp Nov 24, 2023
ef91d0b
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 24, 2023
6170fcc
make split_up handle brackets properly
phlptp Nov 25, 2023
e0c8750
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 25, 2023
81dd146
another test
phlptp Nov 26, 2023
77f3804
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 26, 2023
0eefb2a
handle empty option name in config file
phlptp Nov 26, 2023
8e4d400
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 26, 2023
61d3e95
another failed fuzz test
phlptp Nov 26, 2023
bb6e6d2
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 26, 2023
e076da2
add bracket sequence capability to split up and better escape sequenc…
phlptp Nov 27, 2023
2ab11c6
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 27, 2023
c9b7008
if an option is only positional there is a requirement to check the n…
phlptp Nov 27, 2023
913d969
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 27, 2023
0c8b1be
fix escaped \ generation
phlptp Nov 27, 2023
3338a65
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 27, 2023
802b886
fully handle and generate escaped strings
phlptp Nov 27, 2023
c3eb5f6
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 27, 2023
36f9a28
add check for positional only options to match with long/short names …
phlptp Nov 28, 2023
f9daeea
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 28, 2023
693b3a5
fix double string escape removal
phlptp Nov 28, 2023
33bde08
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 28, 2023
0c55d49
add check on numeric conversions for file generation
phlptp Nov 29, 2023
2219627
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 29, 2023
7fb06ae
fix a few code warnings
phlptp Nov 29, 2023
02efefd
clear runtime string warning in cpplint
phlptp Nov 29, 2023
6de74fe
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 29, 2023
37ec029
fix another fuzzing issue
phlptp Nov 29, 2023
edf72e2
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 29, 2023
4cfbdda
check for single char quote as a single character
phlptp Nov 29, 2023
381e5d2
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 29, 2023
8319643
fix clang-tidy and add more tests
phlptp Nov 29, 2023
68a3c43
add some more tests of option checks
phlptp Nov 30, 2023
4882066
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 30, 2023
df10e71
fix some issues with the escape characters
phlptp Nov 30, 2023
aed9678
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 30, 2023
636fed4
add a check to prevent same name for short and long options in the sa…
phlptp Nov 30, 2023
44a65e7
style: pre-commit.ci fixes
pre-commit-ci[bot] Nov 30, 2023
178b223
add additional test
phlptp Dec 1, 2023
db0731b
Fix order of single name generation
phlptp Dec 1, 2023
f93f558
style: pre-commit.ci fixes
pre-commit-ci[bot] Dec 1, 2023
735d9e9
clang-tidy fixes
phlptp Dec 1, 2023
b49db16
add more tests for coverage
phlptp Dec 1, 2023
a565a9e
style: pre-commit.ci fixes
pre-commit-ci[bot] Dec 1, 2023
416de75
more testing
phlptp Dec 1, 2023
bb8d846
style: pre-commit.ci fixes
pre-commit-ci[bot] Dec 1, 2023
3d4f203
update book chapter
phlptp Dec 1, 2023
16f4b1a
style: pre-commit.ci fixes
pre-commit-ci[bot] Dec 1, 2023
a014cb3
more test fixes
phlptp Dec 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .codacy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
engines:
rubocop:
enabled: true
duplication:
enabled: true
metrics:
enabled: true
coverage:
enabled: false
languages:

exclude_paths:
- "fuzz/**/*"
- "fuzz/*"
- "scripts/**/*"
- "scripts/*"
- "**.md"
1 change: 1 addition & 0 deletions CPPLINT.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ filter=-readability/nolint # Conflicts with clang-tidy
filter=-readability/check # Catch uses CHECK(a == b) (Tests only)
filter=-build/namespaces # Currently using it for one test (Tests only)
filter=-runtime/references # Requires fundamental change of API, don't see need for this
filter=-runtime/string # Requires not using static const strings which makes thing really annoying
filter=-whitespace/blank_line # Unnecessarily strict with blank lines that otherwise help with readability
filter=-whitespace/indent # Requires strange 3-space indent of private/protected/public markers
filter=-whitespace/parens,-whitespace/braces # Conflict with clang-format
10 changes: 10 additions & 0 deletions book/chapters/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,16 @@ str3 = """\
The key is that the closing of the multiline string must be at the end of a line
and match the starting 3 quote sequence.

### Binary Strings

Config files have a binary conversion capability, this is mainly to support
writing config files but can be used by user generated files as well. Strings
with the form `B"(XXXXX)"` will convert any characters inside the parenthesis
with the form \xHH to the equivalent binary value. The HH are hexadecimal
characters. Characters not in this form will be translated as given. If argument
values with unprintable characters are used to generate a config file this
binary form will be used in the output string.

## Multiple configuration files

If it is desired that multiple configuration be allowed. Use
Expand Down
10 changes: 8 additions & 2 deletions fuzz/cli11_app_fuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {

try {
app->parse(parseString);

} catch(const CLI::ParseError &e) {
//(app)->exit(e);
// this just indicates we caught an error known by CLI
return 0; // Non-zero return values are reserved for future use.
}

return 0; // Non-zero return values are reserved for future use.
// should be able to write the config to a file and read from it again
std::string configOut = app->config_to_str();
app->clear();
std::stringstream out(configOut);
app->parse_from_stream(out);
return 0;
}
7 changes: 7 additions & 0 deletions fuzz/cli11_file_fuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
auto app = fuzzdata.generateApp();
try {
app->parse_from_stream(out);
// should be able to write the config to a file and read from it again
std::string configOut = app->config_to_str();

app->clear();
std::stringstream out(configOut);
app->parse_from_stream(out);

} catch(const CLI::ParseError &e) {
// (app)->exit(e);
// this just indicates we caught an error known by CLI
Expand Down
28 changes: 26 additions & 2 deletions fuzz/fuzzApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ std::shared_ptr<CLI::App> FuzzApp::generateApp() {
auto *vgroup = fApp->add_option_group("vectors");

vgroup->add_option("--vopt1", vv1);
vgroup->add_option("--vopt2", vvs);
vgroup->add_option("--vopt2", vvs)->inject_separator();
vgroup->add_option("--vopt3", vstr);
vgroup->add_option("--vopt4", vecvecd);
vgroup->add_option("--vopt4", vecvecd)->inject_separator();

fApp->add_option("--oopt1", od1);
fApp->add_option("--oopt2", ods);
Expand Down Expand Up @@ -121,6 +121,30 @@ std::shared_ptr<CLI::App> FuzzApp::generateApp() {
sub->add_option("--sdwrap", dwrap);
sub->add_option("--siwrap", iwrap);

auto *resgroup = fApp->add_option_group("outputOrder");

resgroup->add_option("--vA", vstrA)->expected(0, 2)->multi_option_policy(CLI::MultiOptionPolicy::TakeAll);
resgroup->add_option("--vB", vstrB)->expected(0, 2)->multi_option_policy(CLI::MultiOptionPolicy::TakeLast);
resgroup->add_option("--vC", vstrC)->expected(0, 2)->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst);
resgroup->add_option("--vD", vstrD)->expected(0, 2)->multi_option_policy(CLI::MultiOptionPolicy::Reverse);
resgroup->add_option("--vS", val32)->expected(0, 2)->multi_option_policy(CLI::MultiOptionPolicy::Sum);
resgroup->add_option("--vM", mergeBuffer)->expected(0, 2)->multi_option_policy(CLI::MultiOptionPolicy::Join);
resgroup->add_option("--vE", vstrE)->expected(2, 4)->delimiter(',');

auto *vldtr = fApp->add_option_group("validators");

validator_strings.resize(10);
vldtr->add_option("--vdtr1", validator_strings[0])->join()->check(CLI::PositiveNumber);
vldtr->add_option("--vdtr2", validator_strings[1])->join()->check(CLI::NonNegativeNumber);
vldtr->add_option("--vdtr3", validator_strings[2])->join()->check(CLI::NonexistentPath);
vldtr->add_option("--vdtr4", validator_strings[3])->join()->check(CLI::Range(7, 3456));
vldtr->add_option("--vdtr5", validator_strings[4])
->join()
->check(CLI::Range(std::string("aa"), std::string("zz"), "string range"));
vldtr->add_option("--vdtr6", validator_strings[5])->join()->check(CLI::TypeValidator<double>());
vldtr->add_option("--vdtr7", validator_strings[6])->join()->check(CLI::TypeValidator<bool>());
vldtr->add_option("--vdtr8", validator_strings[7])->join()->check(CLI::ValidIPV4);
vldtr->add_option("--vdtr9", validator_strings[8])->join()->transform(CLI::Bound(2, 255));
return fApp;
}

Expand Down
11 changes: 11 additions & 0 deletions fuzz/fuzzApp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class FuzzApp {

std::vector<double> vv1{};
std::vector<std::string> vstr{};

std::vector<std::vector<double>> vecvecd{};
std::vector<std::vector<std::string>> vvs{};
std::optional<double> od1{};
Expand Down Expand Up @@ -103,5 +104,15 @@ class FuzzApp {
std::string buffer{};
int intbuffer{0};
std::atomic<double> doubleAtomic{0.0};

// for testing restrictions and reduction methods
std::vector<std::string> vstrA{};
std::vector<std::string> vstrB{};
std::vector<std::string> vstrC{};
std::vector<std::string> vstrD{};
std::vector<std::string> vstrE{};
std::vector<std::string> vstrF{};
std::string mergeBuffer{};
std::vector<std::string> validator_strings{};
};
} // namespace CLI
1 change: 1 addition & 0 deletions fuzz/fuzzCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ int main(int argc, char **argv) {
(app)->exit(e);
// this just indicates we caught an error known by CLI
}

return 0;
}
16 changes: 16 additions & 0 deletions fuzz/fuzz_dictionary1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
"--siwrap"
"--svtup"
"--satd"
"--vA"
"--vB"
"--vC"
"--vD"
"--vS"
"--vM"
"--vE"
"--vdtr"
"nflag2"
"stup1"
"svtup"
Expand Down Expand Up @@ -143,6 +151,7 @@
"stup4"
"sdwrap"
"siwrap"
"vdtr"
"svtup"
"satd"
"%%"
Expand All @@ -156,3 +165,10 @@
"!"
"{"
"}"
"vA"
"vB"
"vC"
"vD"
"vS"
"vM"
"vE"
8 changes: 8 additions & 0 deletions fuzz/fuzz_dictionary2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"svopt4"
"config"
"nflag2"
"vdtr"
"--"
"fuzzer"
"t-"
Expand All @@ -82,3 +83,10 @@
"dexists"
"fexists"
"fnexists"
"vA"
"vB"
"vC"
"vD"
"vS"
"vM"
"vE"
5 changes: 4 additions & 1 deletion include/CLI/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ namespace CLI {
// [CLI11:config_hpp:verbatim]
namespace detail {

std::string convert_arg_for_ini(const std::string &arg, char stringQuote = '"', char characterQuote = '\'');
std::string convert_arg_for_ini(const std::string &arg,
char stringQuote = '"',
char characterQuote = '\'',
bool disable_multi_line = false);

/// Comma separated join, adds quotes if needed
std::string ini_join(const std::vector<std::string> &args,
Expand Down
2 changes: 1 addition & 1 deletion include/CLI/ConfigFwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
// [CLI11:public_includes:end]
Expand All @@ -29,7 +30,6 @@ struct ConfigItem {

/// This is the name
std::string name{};

/// Listing of inputs
std::vector<std::string> inputs{};

Expand Down
3 changes: 3 additions & 0 deletions include/CLI/Error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class BadNameString : public ConstructionError {
return BadNameString("Long names strings require 2 dashes " + name);
}
static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); }
static BadNameString BadPositionalName(std::string name) {
return BadNameString("Invalid positional Name: " + name);
}
static BadNameString DashesOnly(std::string name) {
return BadNameString("Must have a name, not just dashes: " + name);
}
Expand Down
12 changes: 6 additions & 6 deletions include/CLI/Option.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,12 +550,12 @@ class Option : public OptionBase<Option> {
if(!lnames_.empty()) {
return lnames_[0];
}
if(!pname_.empty()) {
return pname_;
}
if(!snames_.empty()) {
return snames_[0];
}
if(!pname_.empty()) {
return pname_;
}
return envname_;
}
/// The number of times the option expects to be included
Expand All @@ -578,13 +578,13 @@ class Option : public OptionBase<Option> {
CLI11_NODISCARD int get_items_expected() const { return get_items_expected_min(); }

/// True if the argument can be given directly
CLI11_NODISCARD bool get_positional() const { return pname_.length() > 0; }
CLI11_NODISCARD bool get_positional() const { return !pname_.empty(); }

/// True if option has at least one non-positional name
CLI11_NODISCARD bool nonpositional() const { return (snames_.size() + lnames_.size()) > 0; }
CLI11_NODISCARD bool nonpositional() const { return (!lnames_.empty() || !snames_.empty()); }

/// True if option has description
CLI11_NODISCARD bool has_description() const { return description_.length() > 0; }
CLI11_NODISCARD bool has_description() const { return !description_.empty(); }

/// Get the description
CLI11_NODISCARD const std::string &get_description() const { return description_; }
Expand Down
40 changes: 32 additions & 8 deletions include/CLI/StringTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,16 @@ CLI11_INLINE std::ostream &format_aliases(std::ostream &out, const std::vector<s

/// Verify the first character of an option
/// - is a trigger character, ! has special meaning and new lines would just be annoying to deal with
template <typename T> bool valid_first_char(T c) { return ((c != '-') && (c != '!') && (c != ' ') && c != '\n'); }
template <typename T> bool valid_first_char(T c) {
return ((c != '-') && (static_cast<unsigned char>(c) > 33)); // space and '!' not allowed
}

/// Verify following characters of an option
template <typename T> bool valid_later_char(T c) {
// = and : are value separators, { has special meaning for option defaults,
// and \n would just be annoying to deal with in many places allowing space here has too much potential for
// inadvertent entry errors and bugs
return ((c != '=') && (c != ':') && (c != '{') && (c != ' ') && c != '\n');
// and control codes other than tab would just be annoying to deal with in many places allowing space here has too
// much potential for inadvertent entry errors and bugs
return ((c != '=') && (c != ':') && (c != '{') && ((static_cast<unsigned char>(c) > 32) || c == '\t'));
}

/// Verify an option/subcommand name
Expand Down Expand Up @@ -211,17 +213,39 @@ template <typename Callable> inline std::string find_and_modify(std::string str,
}

/// Split a string '"one two" "three"' into 'one two', 'three'
/// Quote characters can be ` ' or "
CLI11_INLINE std::vector<std::string> split_up(std::string str, char delimiter = '\0');
/// Quote characters can be ` ' or " or bracket characters [{(< with matching to the matching bracket
CLI11_INLINE std::vector<std::string> split_up(std::string str, char delimiter = '\0', bool removeQuotes = true);

/// get the value of an environmental variable or empty string if empty
CLI11_INLINE std::string get_environment_value(const std::string &env_name);

/// This function detects an equal or colon followed by an escaped quote after an argument
/// then modifies the string to replace the equality with a space. This is needed
/// to allow the split up function to work properly and is intended to be used with the find_and_modify function
/// the return value is the offset+1 which is required by the find_and_modify function.
CLI11_INLINE std::size_t escape_detect(std::string &str, std::size_t offset);

/// get the value of an environmental variable or empty string if empty
CLI11_INLINE std::string get_environment_value(const std::string &env_name);
/// @brief detect if a string has escapable characters
/// @param str the string to do the detection on
/// @return true if the string has escapable characters
CLI11_INLINE bool has_escapable_character(const std::string &str);

/// @brief escape all escapable characters
/// @param str the string to escape
/// @return a string with the escapble characters escaped with '\'
CLI11_INLINE std::string add_escaped_characters(const std::string &str);

/// @brief replace the escaped characters with their equivalent
CLI11_INLINE std::string remove_escaped_characters(const std::string &str);

/// generate a string with all non printable characters escaped to hex codes
CLI11_INLINE std::string binary_escape_string(const std::string &string_to_escape);

CLI11_INLINE bool is_binary_escaped_string(const std::string &escaped_string);

/// extract an escaped binary_string
CLI11_INLINE std::string extract_binary_string(const std::string &escaped_string);

} // namespace detail

// [CLI11:string_tools_hpp:end]
Expand Down
Loading