fix: preserve quoted args when deferring to tagged install script (#5363)

The installer word-split the original arguments when piping into a tagged release's `install.sh`, so `-b '/tmp/syft install path'` arrived as three words and the trailing word was treated as a release tag.

- argument parsing moved into `parse_install_args` so `main` keeps its original args
- tagged script is invoked with `"$@"` instead of the unquoted `PROGRAM_ARGS`

Port of anchore/grype#3738

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2026-10-01 15:00:50 -04:00
committed by GitHub
parent ef356eccea
commit cc326e45a6
2 changed files with 48 additions and 4 deletions
+7 -4
View File
@@ -8,7 +8,6 @@ REPO="${PROJECT_NAME}"
GITHUB_DOWNLOAD_PREFIX=https://github.com/${OWNER}/${REPO}/releases/download
INSTALL_SH_BASE_URL=https://get.anchore.io/${PROJECT_NAME}
LEGACY_INSTALL_SH_BASE_URL=https://raw.githubusercontent.com/${OWNER}/${PROJECT_NAME}
PROGRAM_ARGS=$@
# signature verification options
@@ -791,7 +790,7 @@ prep_signature_verification() {
fi
}
main() (
parse_install_args() {
# parse arguments
# note: never change default install directory (this must always be backwards compatible)
@@ -831,6 +830,11 @@ EOF
set +u
tag=$1
set -u
}
main() (
parse_install_args "$@"
if [ -z "${tag}" ]; then
log_info "checking github for the current release tag"
@@ -838,7 +842,6 @@ EOF
else
log_info "checking github for release tag='${tag}'"
fi
set -u
if ! tag=$(get_release_tag "${OWNER}" "${REPO}" "${tag}"); then
log_err "unable to find tag='${tag}'"
@@ -869,7 +872,7 @@ EOF
log_warn "failed to fetch from ${INSTALL_SH_BASE_URL}, trying fallback URL"
install_script=$(http_copy "${LEGACY_INSTALL_SH_BASE_URL}/${tag}/install.sh" "")
fi
echo "${install_script}" | sh -s -- ${PROGRAM_ARGS}
echo "${install_script}" | sh -s -- "$@"
exit $?
fi
+41
View File
@@ -0,0 +1,41 @@
. test_harness.sh
# make certain main defers to the (stubbed) tagged release script regardless of the caller's env
DOWNLOAD_TAG_INSTALL_SCRIPT=true
get_release_tag() {
printf '%s\n' "$3"
}
prep_signature_verification() {
return 0
}
# the "tagged release script" records each argument it receives, one bracketed arg per line
http_copy() {
cat <<'SCRIPT'
printf '[%s]\n' "$@" > "$INSTALL_ARG_CAPTURE"
SCRIPT
}
test_release_script_receives_original_args() {
test_dir=$(mktemp -d)
INSTALL_ARG_CAPTURE="${test_dir}/actual"
export INSTALL_ARG_CAPTURE
# note: paths are read here instead of passed to run_test_case, which word-splits its arguments
while IFS= read -r install_path; do
main -b "${install_path}" -d v0.80.0
printf '[%s]\n' -b "${install_path}" -d v0.80.0 > "${test_dir}/expected"
assertFilesEqual "${test_dir}/expected" "${INSTALL_ARG_CAPTURE}" "args forwarded to the release script should match the original args (path='${install_path}')"
done <<'PATHS'
/tmp/bin with spaces
/tmp/bin*
/tmp/it's "quoted"
PATHS
rm -rf -- "${test_dir}"
}
run_test_case test_release_script_receives_original_args