Skip to content

DefaultParser rejects a numerical argument in every position but where an option value is pending - #452

Open
simpleqt wants to merge 1 commit into
apache:masterfrom
simpleqt:fix/negative-number-argument
Open

simpleqt wants to merge 1 commit into
apache:masterfrom
simpleqt:fix/negative-number-argument

Conversation

@simpleqt

@simpleqt simpleqt commented Nov 4, 2026

Copy link
Copy Markdown

DefaultParser recognizes a numerical argument, but only consults that test when an option is waiting for its value: isArgument() is called from handleToken() for the pending currentOption (DefaultParser.java:609). A negative number in any other position falls through to handleShortAndLongOption() and then to handleUnknownToken(), which throws for any token that starts with a dash (DefaultParser.java:632-635):

new DefaultParser().parse(new Options(), new String[] { "-1" });
// UnrecognizedOptionException: Unrecognized option: -1

The same happens after a complete option and its value (-b value -1), after a flag (-a -1), at the start of the line (-1 -a) and for the second of two negative numbers (-b -1 -1.5, where the first is correctly consumed as the value of -b).

This contradicts the behaviour recorded in the release notes: CLI-184, "Negative numerical arguments take precedence over numerical options (only supported by the new DefaultParser)", and CLI-150, "Negative numbers mistaken for options". Today the precedence only exists while an option value is pending, so a program invoked as tool -1 always aborts with UnrecognizedOptionException unless the caller writes tool -- -1.

Fix: in handleToken(), route a token that is a negative number and does not match a registered option to the arguments. Everything else is unchanged:

  • a registered option that looks like a number still wins: with an option -1, parse(opts, "-1", "-2") sets -1 and puts -2 in the arguments;
  • -b -1 still consumes -1 as the value of -b (the value path is untouched);
  • -- still sends every following token to the arguments;
  • the NonOptionAction modes keep their meaning (IGNORE/SKIP/STOP are not reached for a negative number).

Validation:

  • New tests DefaultParserTest#testNegativeNumberArgument, #testNegativeNumberOption and #testNegativeNumberAfterEndOfOptions.
  • On the pre-fix base the first two fail with UnrecognizedOptionException: Unrecognized option: -1 / -2; with the fix all pass.
  • Full mvn test passes (1005 tests, 0 failures) and checkstyle reports 0 violations.

No src/changes/changes.xml entry is included because the action format requires a JIRA issue key and I do not have a JIRA account. Happy to add one, e.g.:

<action type="fix" dev="simpleqt" due-to="simpleqt" issue="CLI-xxx">A numerical argument is an argument in every position on the command line, not only where an option value is pending (CLI-184).</action>

AI assistance used to diagnose and fix this defect; the analysis and the change have been reviewed and verified as described above.

DefaultParser recognizes a numerical argument, but only consults that check when
an option is waiting for its value (isArgument() is called from handleToken()
for the currentOption). A negative number in any other position therefore falls
through to handleUnknownToken(), which throws for any token that starts with a
dash:

    new DefaultParser().parse(new Options(), new String[] {"-1"});
    // UnrecognizedOptionException: Unrecognized option: -1

The same happens after a complete option and its value (-b value -1), after a
flag (-a -1) and for the second of two negative numbers (-b -1 -1.5). The
changelog entry for CLI-184 states that "negative numerical arguments take
precedence over numerical options", so a standalone negative number is expected
to be an argument.

Route a token that is a negative number and is not a registered option to the
arguments; tokens that match an option are still parsed as options, and the --
end-of-options marker is unchanged.

Assisted-By: DeepSeek dsv41
Signed-off-by: simpleqt <2015900818@qq.com>
Copilot AI balanced review requested due to automatic review settings November 4, 2026 19:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants