diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-11 02:37:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-11 02:37:48 +0200 |
commit | 9a7d0a01918df5a963b6c90177b321ff743282b2 (patch) | |
tree | 3378d6ce2ad70e7bc34423bd59ca49e5e9aa1304 | |
parent | 81f962f3df0d7194b7a52c6f83259727759094c4 (diff) | |
download | busybox-9a7d0a01918df5a963b6c90177b321ff743282b2.tar.gz |
shell: add OPTARG poisoning to getopt_optarg.tests
ash fails this!
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rwxr-xr-x | shell/ash_test/ash-getopts/getopt_optarg.tests | 2 | ||||
-rw-r--r-- | shell/hush.c | 19 | ||||
-rwxr-xr-x | shell/hush_test/hush-getopts/getopt_optarg.tests | 2 |
3 files changed, 18 insertions, 5 deletions
diff --git a/shell/ash_test/ash-getopts/getopt_optarg.tests b/shell/ash_test/ash-getopts/getopt_optarg.tests index b346284f0..33682e868 100755 --- a/shell/ash_test/ash-getopts/getopt_optarg.tests +++ b/shell/ash_test/ash-getopts/getopt_optarg.tests @@ -4,6 +4,7 @@ var=QWERTY OPTARG=ASDFGH while getopts "w:et" var; do echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" + OPTARG=ASDFGH done echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" @@ -12,5 +13,6 @@ echo "*** OPTIND=0, optstring:'w:et' args:$*" OPTIND=0 while getopts "w:et" var; do echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" + OPTARG=ASDFGH done echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" diff --git a/shell/hush.c b/shell/hush.c index f9a8de423..dc05f24b9 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9872,7 +9872,8 @@ static int FAST_FUNC builtin_shift(char **argv) #if ENABLE_HUSH_GETOPTS static int FAST_FUNC builtin_getopts(char **argv) { -/* +/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html + TODO: If an invalid option is seen, getopts places ? into VAR and, if not silent, prints an error message and unsets OPTARG. If @@ -9886,6 +9887,8 @@ colon (:) is placed in VAR and OPTARG is set to the option character found. Test that VAR is a valid variable name? + +"Whenever the shell is invoked, OPTIND shall be initialized to 1" */ char cbuf[2]; const char *cp, *optstring, *var; @@ -9920,14 +9923,20 @@ Test that VAR is a valid variable name? exitcode = EXIT_FAILURE; c = '?'; } - if (optarg) - set_local_var_from_halves("OPTARG", optarg); - else - unset_local_var("OPTARG"); cbuf[0] = c; cbuf[1] = '\0'; set_local_var_from_halves(var, cbuf); set_local_var_from_halves("OPTIND", utoa(optind)); + + /* Always set or unset, never left as-is, even on exit/error: + * "If no option was found, or if the option that was found + * does not have an option-argument, OPTARG shall be unset." + */ + if (optarg) + set_local_var_from_halves("OPTARG", optarg); + else + unset_local_var("OPTARG"); + return exitcode; } #endif diff --git a/shell/hush_test/hush-getopts/getopt_optarg.tests b/shell/hush_test/hush-getopts/getopt_optarg.tests index b346284f0..33682e868 100755 --- a/shell/hush_test/hush-getopts/getopt_optarg.tests +++ b/shell/hush_test/hush-getopts/getopt_optarg.tests @@ -4,6 +4,7 @@ var=QWERTY OPTARG=ASDFGH while getopts "w:et" var; do echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" + OPTARG=ASDFGH done echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" @@ -12,5 +13,6 @@ echo "*** OPTIND=0, optstring:'w:et' args:$*" OPTIND=0 while getopts "w:et" var; do echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" + OPTARG=ASDFGH done echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" |