class
Analyzer::Groovy::Cli
- Analyzer::Groovy::Cli
- Analyzer
- Reference
- Object
Overview
Surfaces the command-line attack surface of Groovy programs as cli://
endpoints: the built-in CliBuilder (and picocli @Option), JCommander
(@Parameter / addCommand subcommands) and Commons CLI (Option.builder /
addOption), plus System.getenv. Line-scan; attribution for JCommander
subcommands additionally uses a per-file pre-scan (variable -> class ->
command name) so it can resolve both the inline
addCommand("name", new Class()) form and the more common
declare-then-register addCommand("name", instance) form. Root
attribution otherwise (CliBuilder/Commons CLI are flat), merged by URL.
NOTE like CliBuilder, this is a per-file analyzer. When a JCommander
subcommand class lives in its own file (registration call in one file,
@Parameter fields in another), the class-to-command mapping built here
won't span files, so that subcommand's fields fall back to that file's
own root endpoint instead of being attributed under the real
subcommand's URL. A cross-file pre-pass would be needed to close that
gap; not attempted here.
Defined in:
analyzer/analyzers/groovy/cli.crConstant Summary
-
CLASS_DECL =
/\bclass\s+([A-Za-z_]\w*)/ -
CLI_MARKER =
/\bimport\s+org\.apache\.commons\.cli\b|\bOption\.builder\s*\(/ -
--- Commons CLI ------------------------------------------------------
-
CLI_OPT =
/\bcli\.([A-Za-z_]\w*)\s*\(([^)]*)/ -
CLI_TEST_PATH_RE =
Regex.union("/test/", "spec.groovy", "test.groovy") -
One precompiled
Regex.unionscan (PCRE2 JIT) replaces three separateString#includes?scans of the same buffer -- Crystal'sincludes?is not Boyer-Moore accelerated, so a single regex pass over the downcased path is cheaper than three. Equivalent to the OR-of-substrings it replaces (union escapes each literal). -
COMMONS_CLI_ADD_OPT =
/\.addOption\s*\(\s*['"]([^'"]+)['"]\s*,\s*['"]([^'"]+)['"]\s*,/ -
COMMONS_CLI_BUILDER =
/Option\.builder\s*\(\s*(?:['"]([^'"]*)['"])?\s*\)/ -
COMMONS_CLI_LONGOPT =
/\.longOpt\s*\(\s*['"]([^'"]+)['"]/ -
GET_ENV =
/\bSystem\.getenv\s*\(\s*['"]([^'"]+)['"]/ -
JC_ADD_CMD_STR =
/\.addCommand\s*\(\s*['"]([^'"]+)['"]\s*,\s*new\s+([A-Za-z_]\w*)\s*\(/ -
JC_ADD_CMD_VAR =
/\.addCommand\s*\(\s*['"]([^'"]+)['"]\s*,\s*([A-Za-z_]\w*)\s*\)/ -
JC_COMMAND_NAMES =
/@Parameters\s*\([^)]*\bcommandNames\s*=\s*\{?\s*['"]([^'"]+)['"]/ -
JC_MARKER =
/\bimport\s+com\.beust\.jcommander\b|\bnew\s+JCommander\s*\(|\bJCommander\.newBuilder\s*\(/ -
--- JCommander ----------------------------------------------------- Gated on library-specific constructs only (never a bare
@Parameter, which is too generic on its own) so unrelated annotations/classes named similarly don't light this up. -
JC_PARAMETER =
/@Parameter\s*\(([^)]*)\)/ -
LONGOPT =
/longOpt:\s*['"]([^'"]+)['"]/ -
MARKERS =
/\bnew\s+CliBuilder\b|\bCliBuilder\s*\(|@picocli|@Command\b/ -
NON_OPTION =
Set {"parse", "usage", "with", "width", "header", "footer", "stopAtNonOption", "expandArgumentFiles", "posix", "errorWriter", "writer", "name"} -
CliBuilder methods that are not option definitions.
-
OPTION_ATTR =
/@Option\s*\(([^)]*)\)/ -
VAR_NEW_DECL =
/\b[A-Za-z_]\w*\s+([A-Za-z_]\w*)\s*=\s*new\s+([A-Za-z_]\w*)\s*\(/ -
WEB_RE =
/\bimport\s+(?:grails|org\.springframework)\b|@Controller\b|@RestController\b/