]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
getopt: fix fencepost error in ambiguous-W-option handling
authorZack Weinberg <zackw@panix.com>
Sat, 1 Apr 2017 14:01:40 +0000 (10:01 -0400)
committerZack Weinberg <zackw@panix.com>
Fri, 7 Apr 2017 11:47:58 +0000 (07:47 -0400)
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.

* posix/getopt.c (_getopt_internal_r): Don't increment
d->optind a second time when reporting ambiguous -W options.

ChangeLog
posix/getopt.c

index ba702c0efdedc826e8a1004efd6927aa783a3217..48e5b036d949947e43e6b778de34a8a3c9f9546a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2017-04-07  Zack Weinberg  <zackw@panix.com>
 
+       * posix/getopt.c (_getopt_internal_r): Don't increment
+       d->optind a second time when reporting ambiguous -W options.
+
        * posix/getopt_int.h: Include getopt.h.
        Use impl-namespace names for all arguments to _getopt_internal and
        _getopt_internal_r.
index f1fa0166d821f342e5bb0b412aa315aadb2b03bc..e616aa6e4da168e18f322adf45e539ca34491839 100644 (file)
@@ -850,7 +850,6 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 #endif
              }
            d->__nextchar += strlen (d->__nextchar);
-           d->optind++;
            return '?';
          }
        if (pfound != NULL)