class
Analyzer::Cpp::Cli
- Analyzer::Cpp::Cli
- Analyzer
- Reference
- Object
Overview
Surfaces the command-line attack surface of C++ programs as cli://
endpoints: one endpoint per (sub)command with named options
(param_type "flag"), positional arguments ("argument") and consumed
environment variables ("env"). Covers CLI11, getopt/getopt_long, cxxopts,
boost::program_options, gflags, Abseil Flags and p-ranav/argparse, plus
gated getenv reads.
Line-scan analyzer (Go/Ruby/Rust CLI house style) merging endpoints by URL. There is no C++ engine, so it subclasses Analyzer directly.
Defined in:
analyzer/analyzers/cpp/cli.crConstant Summary
-
ABSL_FLAG_MARK =
/\bABSL_FLAG\s*\(/ -
Abseil Flags.
ABSL_FLAG(type, name, default, help)— the type is matched with a depth-aware manual scan (seeabsl_flag_names) rather than a character-class regex, so a template type with a top-level comma (e.g.std::map<std::string,int>) doesn't truncate/misparse the name field. -
ADD_FLAG =
/(\w+)\s*(?:\.|->)\s*add_flag\s*\(\s*"([^"]+)"/ -
ADD_OPTION =
/(\w+)\s*(?:\.|->)\s*add_option\s*\(\s*"([^"]+)"/ -
APP_DECL =
/\bCLI::App\s+(\w+)/ -
CLI11. Variable-mapped: an option/flag binds to its receiver variable (app vs a subcommand), so a root option declared after a subcommand isn't mis-attributed to it.
-
ARGPARSE_ADD_ARG =
/(\w+)\s*(?:\.|->)\s*add_argument\s*\(\s*"([^"]+)"(?:\s*,\s*"([^"]+)")?/ -
ARGPARSE_DECL =
/\bargparse::ArgumentParser\s+(\w+)\s*\(\s*"([^"]+)"/ -
p-ranav/argparse. Declare-then-register style: an ArgumentParser variable's role (root vs subcommand) is only known once it's observed either as the receiver of
.parse_args(argc, argv)/ owner side of.add_subparser(...), or by elimination when it's the file's only declared parser. Resolved once per file inresolve_argparse_varsbefore options are attributed, so declaration order in the file never decides which parser is root (a helper-function-local parser can never be mistaken for the real root). -
ARGPARSE_PARSE =
/(\w+)\s*(?:\.|->)\s*parse_args\s*\(\s*argc\s*,\s*argv\s*\)/ -
ARGPARSE_SUBPARSER =
/(\w+)\s*(?:\.|->)\s*add_subparser\s*\(\s*(\w+)\s*\)/ -
ARGV_IDX =
/\bargv\s*\[\s*(\d+)\s*\]/ -
CLI_MARKERS_RE =
Regex.union("CLI::App", "getopt", "struct option", "cxxopts::", "program_options", "DEFINE_string", "DEFINE_int", "DEFINE_bool", "ABSL_FLAG", "argparse::ArgumentParser") -
Whitespace-tolerant substring markers (no trailing "(" on macro-style entries) so this gate can never diverge from what the extraction regexes above actually accept, e.g.
ABSL_FLAG (int32_t, ...)with a space before the paren is valid C++ and must not be silently skipped. Precompiled as a single Regex.union so the per-file evidence gate costs one PCRE2 match instead of up to ten naive substring scans. -
CPP_TEST_PATH_RE =
Regex.new((Regex.union("/test/", "/tests/", "_test.", "test_", ".test.")).source, Regex::Options::IGNORE_CASE) -
Precompiled union for the per-file test-path skip gate (cpp_test_path?), matched via String#matches? instead of five naive substring scans.
-
EXTS =
[".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx"] -
GETENV =
/\b(?:std::)?getenv\s*\(\s*"([^"]+)"/ -
GETOPT_CALL =
/\bgetopt(?:_long)?\s*\([^,]+,[^,]+,\s*"([^"]*)"/ -
GFLAGS_DEF =
/\bDEFINE_(?:string|int32|int64|bool|double|uint32|uint64)\s*\(\s*(\w+)/ -
gflags.
-
LONG_OPT_ENTRY =
/\{\s*"([A-Za-z0-9][\w-]*)"\s*,\s*(?:no_argument|required_argument|optional_argument|\d)/ -
getopt_long struct option entries + short spec.
-
OPTS_CALL =
/add_options\s*\(\s*\)/ -
OPTS_PAIR =
/(?<!\w)\(\s*"([A-Za-z0-9][\w,-]*)"\s*,/ -
cxxopts / boost::program_options option specs are bare
("name", ...)grouping/chaining calls — the(is preceded by)or whitespace, not an identifier (which would make it a helper call like default_value(...)). -
SUBCOMMAND =
/(?:\.|->)\s*add_subcommand\s*\(\s*"([^"]+)"/ -
SUBCOMMAND_VAR =
/(\w+)\s*=\s*\w+\s*(?:\.|->)\s*add_subcommand\s*\(\s*"([^"]+)"/ -
WEB_RE =
/\b(?:Crow|crow|drogon|httplib|oatpp)\b|Crow::|drogon::|httplib::|oatpp::/