parse-options: fully disable option abbreviation with PARSE_OPT_KEEP_UNKNOWN

baa4adc66a (parse-options: disable option abbreviation with
PARSE_OPT_KEEP_UNKNOWN, 2019-01-27) turned off support for abbreviated
options when the flag PARSE_OPT_KEEP_UNKNOWN is given, as any shortened
option could also be an abbreviation for one of the unknown options.

The code for handling abbreviated options is guarded by an if, but it
can also be reached via goto.  baa4adc66a only blocked the first way.
Add the condition to the other ones as well.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe 2024-01-20 15:39:38 +01:00 committed by Junio C Hamano
parent 564d0252ca
commit 5825268db1
2 changed files with 11 additions and 3 deletions

View file

@ -358,6 +358,7 @@ static enum parse_opt_result parse_long_opt(
const char *arg_end = strchrnul(arg, '=');
const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
enum opt_parsed abbrev_flags = OPT_LONG, ambiguous_flags = OPT_LONG;
int allow_abbrev = !(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT);
for (; options->type != OPTION_END; options++) {
const char *rest, *long_name = options->long_name;
@ -373,7 +374,7 @@ static enum parse_opt_result parse_long_opt(
rest = NULL;
if (!rest) {
/* abbreviated? */
if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
if (allow_abbrev &&
!strncmp(long_name, arg, arg_end - arg)) {
is_abbreviated:
if (abbrev_option &&
@ -397,7 +398,7 @@ static enum parse_opt_result parse_long_opt(
if (options->flags & PARSE_OPT_NONEG)
continue;
/* negated and abbreviated very much? */
if (starts_with("no-", arg)) {
if (allow_abbrev && starts_with("no-", arg)) {
flags |= OPT_UNSET;
goto is_abbreviated;
}
@ -412,7 +413,8 @@ static enum parse_opt_result parse_long_opt(
flags |= OPT_UNSET;
if (!skip_prefix(arg + 3, long_name, &rest)) {
/* abbreviated and negated? */
if (starts_with(long_name, arg + 3))
if (allow_abbrev &&
starts_with(long_name, arg + 3))
goto is_abbreviated;
else
continue;

View file

@ -666,4 +666,10 @@ test_expect_success 'diff --default-prefix overrides diff.mnemonicprefix' '
check_prefix actual a/file0 b/file0
'
test_expect_success 'diff --no-renames cannot be abbreviated' '
test_expect_code 129 git diff --no-rename >actual 2>error &&
test_must_be_empty actual &&
grep "invalid option: --no-rename" error
'
test_done