From 366d08c003506c7ed3c040289f191e1f5b3eb4af Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 7 Jul 2011 10:24:20 -0600 Subject: [PATCH] getopt-gnu: avoid crash in glibc getopt Use of "W;" in an option string may be rare, but we might as well avoid crashing on it. * m4/getopt.m4 (gl_GETOPT_CHECK_HEADRS): Detect the problem. * tests/test-getopt.h (test_getopt): Enhance test. * tests/test-getopt_long.h (test_getopt_long): Likewise. * doc/posix-functions/getopt.texi (getopt): Document it. * doc/glibc-functions/getopt_long.texi (getopt_long): Likewise. * doc/glibc-functions/getopt_long_only.texi (getopt_long_only): Likewise. Signed-off-by: Eric Blake --- ChangeLog | 11 +++++++++++ doc/glibc-functions/getopt_long.texi | 4 ++++ doc/glibc-functions/getopt_long_only.texi | 4 ++++ doc/posix-functions/getopt.texi | 4 ++++ m4/getopt.m4 | 9 ++++++++- tests/test-getopt.h | 23 +++++++++++++++++++++++ tests/test-getopt_long.h | 19 +++++++++++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a5d52ee13..e95d288da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-07-07 Eric Blake + + getopt-gnu: avoid crash in glibc getopt + * m4/getopt.m4 (gl_GETOPT_CHECK_HEADRS): Detect the problem. + * tests/test-getopt.h (test_getopt): Enhance test. + * tests/test-getopt_long.h (test_getopt_long): Likewise. + * doc/posix-functions/getopt.texi (getopt): Document it. + * doc/glibc-functions/getopt_long.texi (getopt_long): Likewise. + * doc/glibc-functions/getopt_long_only.texi (getopt_long_only): + Likewise. + 2011-07-07 Ulrich Drepper getopt: handle W; without long options in getopt [BZ #12922] diff --git a/doc/glibc-functions/getopt_long.texi b/doc/glibc-functions/getopt_long.texi index f4d3561c0..c5e86fe92 100644 --- a/doc/glibc-functions/getopt_long.texi +++ b/doc/glibc-functions/getopt_long.texi @@ -37,6 +37,10 @@ MacOS X 10.5, OpenBSD 4.0, AIX 5.2, IRIX 6.5, Solaris 11 2010-11, Cygwin 1.5.x. @item This function is missing on some platforms: AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Interix 3.5. +@item +This function crashes if the option string includes @code{W;} but +there are no long options, on some platforms: +glibc 2.14. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/glibc-functions/getopt_long_only.texi b/doc/glibc-functions/getopt_long_only.texi index 1b90c416f..893167071 100644 --- a/doc/glibc-functions/getopt_long_only.texi +++ b/doc/glibc-functions/getopt_long_only.texi @@ -38,6 +38,10 @@ MacOS X 10.5, OpenBSD 4.0, AIX 5.2, Solaris 11 2010-11, Cygwin 1.5.x. This function is missing on some platforms: MacOS X 10.3, FreeBSD 5.2.1, NetBSD 5.0, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, mingw, Interix 3.5. +@item +This function crashes if the option string includes @code{W;} but +there are no long options, on some platforms: +glibc 2.14. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/posix-functions/getopt.texi b/doc/posix-functions/getopt.texi index bab4922e1..099c2e3d0 100644 --- a/doc/posix-functions/getopt.texi +++ b/doc/posix-functions/getopt.texi @@ -48,6 +48,10 @@ AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Interix 3.5. The function @code{getopt_long_only} is missing on some platforms: MacOS X 10.3, FreeBSD 5.2.1, NetBSD 5.0, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw, Interix 3.5. +@item +This function crashes if the option string includes @code{W;} on some +platforms: +glibc 2.14. @end itemize Portability problems not fixed by Gnulib: diff --git a/m4/getopt.m4 b/m4/getopt.m4 index 4d8450ff9..db586bd7e 100644 --- a/m4/getopt.m4 +++ b/m4/getopt.m4 @@ -1,4 +1,4 @@ -# getopt.m4 serial 35 +# getopt.m4 serial 36 dnl Copyright (C) 2002-2006, 2008-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -281,6 +281,13 @@ dnl is ambiguous with environment values that contain newlines. else if (getopt (3, argv, "+:a:b") != ':') result |= 64; } + /* This code dumps core on glibc 2.14. */ + { + char *argv[] = { "program", "-W", "dummy", NULL }; + optind = opterr = 1; + if (getopt (3, argv, "W;") != 'W') + result |= 128; + } return result; ]])], [gl_cv_func_getopt_gnu=yes], diff --git a/tests/test-getopt.h b/tests/test-getopt.h index 9c877b3d1..e3fc589f5 100644 --- a/tests/test-getopt.h +++ b/tests/test-getopt.h @@ -1365,5 +1365,28 @@ test_getopt (void) ASSERT (optind == 3); ASSERT (!output); } + + /* Check that 'W' does not dump core: + http://sourceware.org/bugzilla/show_bug.cgi?id=12922 + Technically, POSIX says the presence of ';' in the opt-string + gives unspecified behavior, so we only test this when GNU compliance + is desired. */ + for (start = OPTIND_MIN; start <= 1; start++) + { + int argc = 0; + const char *argv[10]; + int c; + int pos = ftell (stderr); + + argv[argc++] = "program"; + argv[argc++] = "-W"; + argv[argc++] = "dummy"; + argv[argc] = NULL; + optind = start; + opterr = 1; + ASSERT (getopt (argc, (char **) argv, "W;") == 'W'); + ASSERT (ftell (stderr) == pos); + ASSERT (optind == 2); + } #endif /* GNULIB_TEST_GETOPT_GNU */ } diff --git a/tests/test-getopt_long.h b/tests/test-getopt_long.h index 7a748674a..c1035b166 100644 --- a/tests/test-getopt_long.h +++ b/tests/test-getopt_long.h @@ -314,6 +314,25 @@ test_getopt_long (void) } } + /* Test that 'W' does not dump core: + http://sourceware.org/bugzilla/show_bug.cgi?id=12922 */ + { + int argc = 0; + const char *argv[10]; + int option_index; + int c; + + argv[argc++] = "program"; + argv[argc++] = "-W"; + argv[argc++] = "dummy"; + argv[argc] = NULL; + optind = 1; + opterr = 0; + c = do_getopt_long (argc, argv, "W;", NULL, &option_index); + ASSERT (c == 'W'); + ASSERT (optind == 2); + } + /* Test processing of boolean short options. */ for (start = 0; start <= 1; start++) { -- 2.11.0