kiss: Disable globbing globally and only enable it when needed.

This commit is contained in:
Dylan Araps 2019-07-21 14:09:53 +03:00
parent b04325d006
commit 703868c0d2
1 changed files with 39 additions and 50 deletions

89
kiss
View File

@ -1,4 +1,9 @@
#!/bin/sh -e #!/bin/sh -ef
#
# Disable warnings against word-splitting and globbing.
# They are used *safely* throughout this script as globbing
# is globally disabled and assumptions can be made about the input.
# shellcheck disable=2046,2086
# #
# This is a simple package manager written in POSIX 'sh' for # This is a simple package manager written in POSIX 'sh' for
# KISS Linux, utilizing the core UNIX utilities where needed. # KISS Linux, utilizing the core UNIX utilities where needed.
@ -67,14 +72,8 @@ pkg_search() {
"Repositories will be searched in the configured order." \ "Repositories will be searched in the configured order." \
"The variable should work just like \$PATH." "The variable should work just like \$PATH."
# Disable globbing with 'set -f' to ensure that the unquoted # Find the repository containing a package.
# variable doesn't expand into anything nasty. set -- "$1" $(IFS=:; find $KISS_PATH -maxdepth 1 -name "$1")
# shellcheck disable=2086,2046
{
set -f
set -- "$1" $(IFS=:; find $KISS_PATH -maxdepth 1 -name "$1")
set +f
}
# A package may also not be found due to a repository not being # A package may also not be found due to a repository not being
# readable by the current user. Either way, we need to die here. # readable by the current user. Either way, we need to die here.
@ -99,7 +98,7 @@ pkg_list() {
# packages. If no arguments are passed, list all. As we # packages. If no arguments are passed, list all. As we
# loop over '$@', if there aren't any arguments we can # loop over '$@', if there aren't any arguments we can
# just set the directory contents to the argument list. # just set the directory contents to the argument list.
[ "$1" ] || set -- * [ "$1" ] || { set +f; set -f -- *; }
# If the 'glob' above failed, exit early as there are no # If the 'glob' above failed, exit early as there are no
# packages installed. # packages installed.
@ -359,15 +358,8 @@ pkg_build() {
# passed to KISS aren't. # passed to KISS aren't.
explicit_packages=" $* " explicit_packages=" $* "
# Disable globbing with 'set -f' to ensure that the unquoted # Set the resolved dependency list as the function's arguments.
# variable doesn't expand into anything nasty. set -- $missing_deps
# shellcheck disable=2086,2046
{
# Set the resolved dependency list as the function's arguments.
set -f
set -- $missing_deps
set +f
}
# The dependency solver always lists all dependencies regardless of # The dependency solver always lists all dependencies regardless of
# whether or not they are installed. Ensure that all explicit packages # whether or not they are installed. Ensure that all explicit packages
@ -385,15 +377,8 @@ pkg_build() {
esac esac
done done
# Disable globbing with 'set -f' to ensure that the unquoted # Set the filtered dependency list as the function's arguments.
# variable doesn't expand into anything nasty. set -- $build_packages
# shellcheck disable=2086,2046
{
# Set the resolved dependency list as the function's arguments.
set -f
set -- $build_packages
set +f
}
log "Building: $*." log "Building: $*."
@ -576,6 +561,9 @@ pkg_conflicts() {
[ "${line%%*/}" ] && printf '%s\n' "$line" >> "$cac_dir/manifest-$pid" [ "${line%%*/}" ] && printf '%s\n' "$line" >> "$cac_dir/manifest-$pid"
done ||: done ||:
# Enable globbing.
set +f
# Compare extracted manifest to all installed manifests. # Compare extracted manifest to all installed manifests.
# If there are matching lines (files) there is a package conflict. # If there are matching lines (files) there is a package conflict.
for db in "$KISS_ROOT/$pkg_db/"*; do for db in "$KISS_ROOT/$pkg_db/"*; do
@ -585,6 +573,9 @@ pkg_conflicts() {
die "Package '$2' conflicts with '${db##*/}'." die "Package '$2' conflicts with '${db##*/}'."
done done
# Disable globbing.
set -f
# Remove this temporary file as we no longer need it. # Remove this temporary file as we no longer need it.
rm -f "$cac_dir/manifest-$pid" rm -f "$cac_dir/manifest-$pid"
} }
@ -600,14 +591,20 @@ pkg_remove() {
return return
} }
# Enable globbing.
set +f
# Make sure that nothing depends on this package. # Make sure that nothing depends on this package.
[ "$2" = check ] && for file in "$KISS_ROOT/$pkg_db/"*; do [ "$2" = check ] && for file in "$KISS_ROOT/$pkg_db/"*; do
# Check each depends file for the package and if it's # Check each depends file for the package and if it's
# a run-time dependency, append to the $required_by string. # a run-time dependency, append to the $required_by string.
grep -q "^$1$" "$file/depends" 2>/dev/null && grep -qFx "$1" "$file/depends" 2>/dev/null &&
required_by="$required_by'${file##*/}', " required_by="$required_by'${file##*/}', "
done done
# Disable globbing.
set -f
[ "$required_by" ] && [ "$required_by" ] &&
die "[$1]: Package is required by ${required_by%, }." \ die "[$1]: Package is required by ${required_by%, }." \
"[$1]: Aborting here..." "[$1]: Aborting here..."
@ -740,19 +737,11 @@ pkg_updates() {
# version and the version in the repositories differ, it's considered # version and the version in the repositories differ, it's considered
# an update. # an update.
# Disable globbing with 'set -f' to ensure that the unquoted
# variable doesn't expand into anything nasty.
# shellcheck disable=2086,2046
{
set -f
IFS=:
set -- $KISS_PATH
IFS=$old_ifs
set +f
}
log "Updating repositories..." log "Updating repositories..."
# Create a list of all repositories.
IFS=:; set -- $KISS_PATH; IFS=$old_ifs
# Update each repository in '$KISS_PATH'. It is assumed that # Update each repository in '$KISS_PATH'. It is assumed that
# each repository is 'git' tracked. # each repository is 'git' tracked.
for repo; do for repo; do
@ -762,6 +751,9 @@ pkg_updates() {
log "Checking for new package versions..." log "Checking for new package versions..."
# Enable globbing.
set +f
for pkg in "$KISS_ROOT/$pkg_db/"*; do for pkg in "$KISS_ROOT/$pkg_db/"*; do
# Find the package's repository files. This needs to keep # Find the package's repository files. This needs to keep
# happening as we can't store this data in any kind of data # happening as we can't store this data in any kind of data
@ -780,20 +772,17 @@ pkg_updates() {
} }
done done
# Disable globbing.
set -f
# End here if no packages have an update. # End here if no packages have an update.
[ "$outdated" ] || { [ "$outdated" ] || {
log "Everything is up to date." log "Everything is up to date."
return return
} }
# Disable globbing with 'set -f' to ensure that the unquoted # Turn the string of outdated packages into a 'list'.
# variable doesn't expand into anything nasty. set -- $outdated
# shellcheck disable=2086,2046
{
set -f
set -- $outdated
set +f
}
log "Packages to update: ${outdated% }." log "Packages to update: ${outdated% }."
@ -813,7 +802,7 @@ pkg_clean() {
rm -rf -- "$mak_dir" "$pkg_dir" "$tar_dir" rm -rf -- "$mak_dir" "$pkg_dir" "$tar_dir"
# Remove temporary files. # Remove temporary files.
rm -f "$repo_dir/.checksums" "$cac_dir/m-"* (set +f; rm -f "$repo_dir/.checksums" "$cac_dir/m-"*)
} }
root_check() { root_check() {
@ -845,7 +834,7 @@ args() {
# Use a glob after 'cd' to generate a list of all installed # Use a glob after 'cd' to generate a list of all installed
# packages based on directory names. # packages based on directory names.
set -- * set +f; set -f -- *
# Undo the above 'cd' to ensure we stay in the same location. # Undo the above 'cd' to ensure we stay in the same location.
cd - >/dev/null cd - >/dev/null