makepkg: do not eval dlcmd

This eval enables the following in a PKGBUILD to "just work":

  source=('$pkgname-$pkgver.tar.gz'::'https://host/$pkgver.tar.gz')

This has at least two problems:

- It violated the principle of least surprise.
- It could be a security issue since URLs are arbitrary input.

Instead, expand the dlagent command line into an array, replace the %o,
%u place holders, and run the resultant command line as is.

Embedded spaces in the DLAGENTS entry can be escaped with a backslash.

Fixes FS#41682

Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
lolilolicon 2014-09-08 00:57:31 +08:00 committed by Allan McRae
parent 95e1a1ef82
commit ee207d7c7b
1 changed files with 10 additions and 11 deletions

View File

@ -342,8 +342,9 @@ download_file() {
local proto=$(get_protocol "$netfile")
# find the client we should use for this URL
local dlcmd
dlcmd=$(get_downloadclient "$proto") || exit $?
local -a cmdline
IFS=' ' read -a cmdline < <(get_downloadclient "$proto")
(( ${#cmdline[@]} )) || exit
local filename=$(get_filename "$netfile")
local url=$(get_url "$netfile")
@ -359,20 +360,18 @@ download_file() {
local dlfile="${url##*/}"
# replace %o by the temporary dlfile if it exists
if [[ $dlcmd = *%o* ]]; then
dlcmd=${dlcmd//\%o/\"$filename.part\"}
dlfile="$filename.part"
if [[ ${cmdline[*]} = *%o* ]]; then
dlfile=$filename.part
cmdline=("${cmdline[@]//%o/"$dlfile"}")
fi
# add the URL, either in place of %u or at the end
if [[ $dlcmd = *%u* ]]; then
dlcmd=${dlcmd//\%u/\"$url\"}
if [[ ${cmdline[*]} = *%u* ]]; then
cmdline=("${cmdline[@]//%u/"$url"}")
else
dlcmd="$dlcmd \"$url\""
cmdline+=("$url")
fi
local ret=0
eval "$dlcmd >&2 || ret=\$?"
if (( ret )); then
if ! command -- "${cmdline[@]}" >&2; then
[[ ! -s $dlfile ]] && rm -f -- "$dlfile"
error "$(gettext "Failure while downloading %s")" "$filename"
plain "$(gettext "Aborting...")"