hush: GETOPT_RESET() _after_ getopts too.
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 29 Aug 2017 12:32:17 +0000 (14:32 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 29 Aug 2017 12:32:17 +0000 (14:32 +0200)
NOEXEC'ed applets which use getopt() need this.

function                                             old     new   delta
builtin_getopts                                      403     413     +10

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/libbb.h
libbb/getopt32.c
shell/hush.c
shell/shell_common.c

index 95a7470a8277b1adbc5a4328b6d991cd09701c3f..06f8877324c91001d59b8453fa3e69d1b0800f49 100644 (file)
@@ -1212,7 +1212,7 @@ uint32_t getopt32long(char **argv, const char *optstring, const char *longopts,
  * By ~2008, OpenBSD 3.4 was changed to survive glibc-like optind = 0
  * (to interpret it as if optreset was set).
  */
-#ifdef __GLIBC__
+#if 1 /*def __GLIBC__*/
 #define GETOPT_RESET() (optind = 0)
 #else /* BSD style */
 #define GETOPT_RESET() (optind = 1)
index f778c6e8912f94ad513761c5dfd3fbe94eca0cb3..3785100634495f0e2d3b95a222bd8239b4ad819e 100644 (file)
@@ -517,7 +517,7 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options,
        }
 
        /* In case getopt32 was already called:
-        * reset the libc getopt() function, which keeps internal state.
+        * reset libc getopt() internal state.
         * run_nofork_applet() does this, but we might end up here
         * also via gunzip_main() -> gzip_main(). Play safe.
         */
index 8e00225319dc3815f37c8dfeea3537bc056a9710..d27550ba066b7959ec7794a5199a0c1081756e34 100644 (file)
@@ -9956,7 +9956,7 @@ Test that VAR is a valid variable name?
         * until we get Nth result (or failure).
         * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set).
         */
-       optind = 0; /* reset getopt() state */
+       GETOPT_RESET();
        count = 0;
        n = string_array_len(argv);
        do {
@@ -9971,6 +9971,7 @@ Test that VAR is a valid variable name?
        /* Set OPTIND. Prevent resetting of the magic counter! */
        set_local_var_from_halves("OPTIND", utoa(optind));
        G.getopt_count = count; /* "next time, give me N+1'th result" */
+       GETOPT_RESET(); /* just in case */
 
        /* Set OPTARG */
        /* Always set or unset, never left as-is, even on exit/error:
index 7a0799ed590938f102069d8dec8b7902ece1bf47..c978693f95ee67caee42f8793f239cf15c0c7f26 100644 (file)
@@ -425,8 +425,8 @@ shell_builtin_ulimit(char **argv)
         * ulimit 123 -c2 -l 456
         */
 
-       /* In case getopt was already called:
-        * reset the libc getopt() function, which keeps internal state.
+       /* In case getopt() was already called:
+        * reset libc getopt() internal state.
         */
        GETOPT_RESET();