Skip to content

Commit

Permalink
Fix quote-armor for the case of ~.
Browse files Browse the repository at this point in the history
Notably, `printf '%q' '~'` will print an unquoted `~`, but _passing_ an
unquoted `~` can end up expanding to `$HOME`.
  • Loading branch information
danfuzz committed Oct 26, 2023
1 parent 877204a commit 31efd86
Showing 1 changed file with 12 additions and 31 deletions.
43 changes: 12 additions & 31 deletions scripts/lib/bashy-core/arg-processor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function opt-action {

if [[ ${optVar} != '' ]]; then
# Set up the variable initializer.
_argproc_initStatements+=("${optVar}=$(_argproc_quote "${optDefault}")")
_argproc_initStatements+=("${optVar}=$(vals "${optDefault}")")
fi
}

Expand Down Expand Up @@ -195,7 +195,7 @@ function opt-toggle {

if [[ ${optVar} != '' ]]; then
# Set up the variable initializer.
_argproc_initStatements+=("${optVar}=$(_argproc_quote "${optDefault}")")
_argproc_initStatements+=("${optVar}=$(vals "${optDefault}")")
fi

_argproc_define-value-taking-arg --option \
Expand Down Expand Up @@ -230,7 +230,7 @@ function opt-value {

if [[ ${optVar} != '' ]]; then
# Set up the variable initializer.
_argproc_initStatements+=("${optVar}=$(_argproc_quote "${optDefault}")")
_argproc_initStatements+=("${optVar}=$(vals "${optDefault}")")
fi

_argproc_define-value-taking-arg --option \
Expand Down Expand Up @@ -263,7 +263,7 @@ function positional-arg {

if [[ ${optVar} != '' ]]; then
# Set up the variable initializer.
_argproc_initStatements+=("${optVar}=$(_argproc_quote "${optDefault}")")
_argproc_initStatements+=("${optVar}=$(vals "${optDefault}")")
fi

_argproc_define-value-taking-arg \
Expand Down Expand Up @@ -498,7 +498,7 @@ function _argproc_define-alias-arg {
error-msg "Value not allowed for '"${desc}"'."
return 1
fi
printf "%q\\n" '"$(_argproc_quote "${args[@]}")"'
printf "%q\\n" '"$(vals "${args[@]}")"'
}'
fi

Expand Down Expand Up @@ -574,7 +574,7 @@ function _argproc_define-no-value-arg {
_argproc_handler-body "${specName}" '' "${callFunc}" "${varName}"
)"

value="$(_argproc_quote "${value}")"
value="$(vals "${value}")"

eval 'function '"${handlerName}"' {
if (( $# > 0 )); then
Expand Down Expand Up @@ -626,7 +626,7 @@ function _argproc_define-value-taking-arg {
error-msg "Value required for '"${desc}"'."
return 1'
else
eqDefault="$(_argproc_quote "${eqDefault:1}")" # `:1` to drop the `=`.
eqDefault="$(vals "${eqDefault:1}")" # `:1` to drop the `=`.
ifNoValue="set -- ${eqDefault}"
fi

Expand Down Expand Up @@ -1013,7 +1013,7 @@ function _argproc_set-arg-description {
esac

eval 'function '"${funcName}"' {
echo '"$(_argproc_quote "${desc}")"'
echo '"$(vals "${desc}")"'
}'
}

Expand Down Expand Up @@ -1057,13 +1057,13 @@ function _argproc_statements-from-args {
'=')
# Single-value option.
_argproc_statements+=(
"${handler} $(_argproc_quote "${value}")")
"${handler} $(vals "${value}")")
;;
'[]=')
# Multi-value option. Parse the value into elements.
if set-array-from-vals values "${value}"; then
_argproc_statements+=(
"${handler} $(_argproc_quote "${values[@]}")")
"${handler} $(vals "${values[@]}")")
else
error-msg "Invalid multi-value syntax for option --${name}:"
error-msg " $(vals -- "${value}")"
Expand Down Expand Up @@ -1133,12 +1133,12 @@ function _argproc_statements-from-args {
break
fi

_argproc_statements+=("${func} $(_argproc_quote "$1")")
_argproc_statements+=("${func} $(vals "$1")")
shift
done

if declare -F _argproc:rest >/dev/null; then
_argproc_statements+=("_argproc:rest $(_argproc_quote "$@")")
_argproc_statements+=("_argproc:rest $(vals "$@")")
elif (( $# > 0 )); then
if (( ${#_argproc_positionalFuncs[@]} == 0 )); then
error-msg 'Positional arguments are not allowed.'
Expand All @@ -1150,22 +1150,3 @@ function _argproc_statements-from-args {

return "${argError}"
}

# Quotes one or more literal strings, space separated, so they can be safely
# used in evaluated code. This (successfully) prints nothing if no arguments are
# given.
function _argproc_quote {
case "$#" in
0)
: # Nothing to print.
;;
1)
printf '%q' "$1"
;;
*)
printf '%q' "$1"
shift
printf ' %q' "$@"
;;
esac
}

0 comments on commit 31efd86

Please sign in to comment.