shell: add OPTARG poisoning to getopt_optarg.tests

ash fails this!

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko
2017-08-11 02:37:48 +02:00
parent 81f962f3df
commit 9a7d0a0191
3 changed files with 18 additions and 5 deletions

View File

@ -4,6 +4,7 @@ var=QWERTY
OPTARG=ASDFGH OPTARG=ASDFGH
while getopts "w:et" var; do while getopts "w:et" var; do
echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"
OPTARG=ASDFGH
done done
echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"
@ -12,5 +13,6 @@ echo "*** OPTIND=0, optstring:'w:et' args:$*"
OPTIND=0 OPTIND=0
while getopts "w:et" var; do while getopts "w:et" var; do
echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"
OPTARG=ASDFGH
done done
echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"

View File

@ -9872,7 +9872,8 @@ static int FAST_FUNC builtin_shift(char **argv)
#if ENABLE_HUSH_GETOPTS #if ENABLE_HUSH_GETOPTS
static int FAST_FUNC builtin_getopts(char **argv) static int FAST_FUNC builtin_getopts(char **argv)
{ {
/* /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
TODO: TODO:
If an invalid option is seen, getopts places ? into VAR and, if If an invalid option is seen, getopts places ? into VAR and, if
not silent, prints an error message and unsets OPTARG. 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. character found.
Test that VAR is a valid variable name? Test that VAR is a valid variable name?
"Whenever the shell is invoked, OPTIND shall be initialized to 1"
*/ */
char cbuf[2]; char cbuf[2];
const char *cp, *optstring, *var; const char *cp, *optstring, *var;
@ -9920,14 +9923,20 @@ Test that VAR is a valid variable name?
exitcode = EXIT_FAILURE; exitcode = EXIT_FAILURE;
c = '?'; c = '?';
} }
if (optarg)
set_local_var_from_halves("OPTARG", optarg);
else
unset_local_var("OPTARG");
cbuf[0] = c; cbuf[0] = c;
cbuf[1] = '\0'; cbuf[1] = '\0';
set_local_var_from_halves(var, cbuf); set_local_var_from_halves(var, cbuf);
set_local_var_from_halves("OPTIND", utoa(optind)); 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; return exitcode;
} }
#endif #endif

View File

@ -4,6 +4,7 @@ var=QWERTY
OPTARG=ASDFGH OPTARG=ASDFGH
while getopts "w:et" var; do while getopts "w:et" var; do
echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"
OPTARG=ASDFGH
done done
echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"
@ -12,5 +13,6 @@ echo "*** OPTIND=0, optstring:'w:et' args:$*"
OPTIND=0 OPTIND=0
while getopts "w:et" var; do while getopts "w:et" var; do
echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"
OPTARG=ASDFGH
done done
echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'" echo "exited: var:'$var' OPTIND:$OPTIND OPTARG:'$OPTARG'"