options-parser: correctly quote shell meta-characters in arguments.

When any argument contains a shell meta-character, it needs to be
quoted when passed around.  We already pass parameter lists as
space delimited strings of arguments, and pass the string through
eval to turn it back into a list before re-assigning using `set'.
To prevent the shell from interpreting any meta-characters during
an `eval set dummy $argumentlist', they must be quoted again
inside the quoted argument list.
* build-aux/funclib.sh (func_quote_for_eval): Be careful to keep
a separate tally of quoted and unquoted argument lists, to
conform to the API of the single argument func_quote_for_eval
implementation in build-aux/general.m4sh.
* bulid-aux/options-parser (func_run_hooks): To account for the
doubly quoted meta-character argument lists, we must eval the
parameter reassignment `set' call separately from evaluating the
dynamically named hook results variable.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
This commit is contained in:
Gary V. Vaughan 2012-10-11 00:09:48 +07:00
parent a73a99b88a
commit 4930ebf6b1
2 changed files with 15 additions and 6 deletions

View File

@ -917,6 +917,7 @@ func_quote_for_eval ()
{
$debug_cmd
func_quote_for_eval_unquoted_result=
func_quote_for_eval_result=
while test 0 -lt $#; do
case $1 in
@ -925,8 +926,13 @@ func_quote_for_eval ()
*)
_G_unquoted_arg=$1 ;;
esac
if test -n "$func_quote_for_eval_unquoted_result"; then
func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
else
func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
fi
case $func_quote_for_eval_unquoted_result in
case $_G_unquoted_arg in
# Double-quote args containing shell metacharacters to delay
# word splitting, command substitution and variable expansion
# for a subsequent eval.
@ -940,9 +946,11 @@ func_quote_for_eval ()
;;
esac
test -n "$func_quote_for_eval_result" \
&& func_append func_quote_for_eval_result " "
func_append func_quote_for_eval_result "$_G_unquoted_arg"
if test -n "$func_quote_for_eval_result"; then
func_append func_quote_for_eval_result " $_G_quoted_arg"
else
func_append func_quote_for_eval_result "$_G_quoted_arg"
fi
shift
done
}

View File

@ -173,7 +173,8 @@ func_run_hooks ()
# store returned options list back into positional
# parameters for next `cmd' execution.
eval set dummy \$${_G_hook}_result; shift
eval _G_hook_result=\$${_G_hook}_result
eval set dummy "$_G_hook_result"; shift
done
func_quote_for_eval ${1+"$@"}
@ -315,7 +316,7 @@ func_parse_options ()
func_run_hooks func_parse_options ${1+"$@"}
# Adjust func_parse_options positional parameters to match
eval set dummy $func_run_hooks_result; shift
eval set dummy "$func_run_hooks_result"; shift
# Break out of the loop if we already parsed every option.
test $# -gt 0 || break