From ae3e58d3dc53a95fde87ea86835d38bdd204dfd2 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Thu, 6 Apr 2017 11:14:13 -0700 Subject: [PATCH] getopt: fix fencepost error in ambiguous-W-option handling getopt_long contains an undocumented (AFAICT) feature in which, if you put "W;" in the short-options list, then '-W foo' and '-Wfoo' are treated as equivalent to '--foo'. This is implemented with a partial second copy of the code for handling long options, and that code increments optind one too many times when recovering from an ambiguous abbreviated option, which can cause the main loop to walk past the end of argv and crash. I discovered this while writing a test case that tries to exercise all of getopt's error reporting paths; I wouldn't be surprised to learn that this feature is never used by real applications. * lib/getopt.c (_getopt_internal_r): Don't increment d->optind a second time when reporting ambiguous -W options. --- ChangeLog | 18 ++++++++++++++++++ lib/getopt.c | 1 - 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e61efb8902..06da4900fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2017-04-06 Zack Weinberg + getopt: fix fencepost error in ambiguous-W-option handling + + getopt_long contains an undocumented (AFAICT) feature in which, if you + put "W;" in the short-options list, then '-W foo' and '-Wfoo' are + treated as equivalent to '--foo'. This is implemented with a partial + second copy of the code for handling long options, and that code + increments optind one too many times when recovering from an ambiguous + abbreviated option, which can cause the main loop to walk past the end + of argv and crash. + + I discovered this while writing a test case that tries to exercise all + of getopt's error reporting paths; I wouldn't be surprised to learn + that this feature is never used by real applications. + + * lib/getopt.c (_getopt_internal_r): Don't increment + d->optind a second time when reporting ambiguous -W options. + + getopt: clean up getopt.c and getopt1.c file headers In getopt.c, there is no need to include wchar.h at all, and it is diff --git a/lib/getopt.c b/lib/getopt.c index 559e03bed3..757856b446 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -887,7 +887,6 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, #endif } d->__nextchar += strlen (d->__nextchar); - d->optind++; return '?'; } if (pfound != NULL) -- 2.39.5