summaryrefslogtreecommitdiff
path: root/bin/rcup.in
diff options
context:
space:
mode:
authorGravatar Edd Salkield <edd@salkield.uk>2020-01-18 18:40:45 +0000
committerGravatar Mike Burns <mburns@thoughtbot.com>2020-04-03 16:21:07 -0400
commitcbc346b279b5c08b281c9901b994a58eb037a60d (patch)
tree387a6fd63a9332e43ca9f29a4b65ada39f85f45d /bin/rcup.in
parentf2fb351c391dca7c188a8623e71519619c2ce9a0 (diff)
Fix shell globbing bugs
There are several problems leading to the unintentional globbing issue: Firstly, within `rcup` and `rcdn`, when constructing arguments to pass to `lsrc`, the _for_ loops over the arguments do not have quoted variables, leading to globbing. I have quoted these accordingly. Secondly, `lsrc` is invoked as follows: ```sh dests_and_srcs="$(lsrc $LS_ARGS)" ``` When shells use command substitution like this, they go through two stages: - Word expansion. This is useful because it splits `LS_ARGS` back up into its constituent strings. - File name expansion. The side effect of this is to introduce globbing. You can read more about how this works [here](https://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html#sect_03_04_07). To fix this, I have passed `lsrc` and its arguments to `eval`. This involves quoting the relevant arguments, so: ```sh for dotfiles_dir in "$DOTFILES_DIRS"; do LS_ARGS="$LS_ARGS -d $dotfiles_dir" done ``` becomes ```sh for dotfiles_dir in "$DOTFILES_DIRS"; do LS_ARGS="$LS_ARGS -d \"$dotfiles_dir\"" done ``` Then `lsrc` is invoked as follows: ```sh dests_and_srcs="$(eval "lsrc $LS_ARGS")" ``` There is one final non-globbing issue: the parsing of arguments can introduce extra spaces in the variables, which then trip up the `dotfiles_dir_excludes` function. For example: ```sh I) includes="$includes $OPTARG";; ``` introduces a space if `includes` is empty or null. I have introduced the function `append_variable`, which allows two variables to be appended without introducing unnecessary whitespace. Then the additional whitespace is never added in the first place. Fixes #256.
Diffstat (limited to 'bin/rcup.in')
-rwxr-xr-xbin/rcup.in50
1 files changed, 25 insertions, 25 deletions
diff --git a/bin/rcup.in b/bin/rcup.in
index 78f5faa..65f0ab8 100755
--- a/bin/rcup.in
+++ b/bin/rcup.in
@@ -213,23 +213,23 @@ handle_command_line() {
case "$opt" in
B) hostname="$OPTARG" ;;
C) always_copy=1 ;;
- d) dotfiles_dirs="$dotfiles_dirs $OPTARG" ;;
+ d) dotfiles_dirs="$(append_variable "$dotfiles_dirs" "$OPTARG")" ;;
f) REPLACE_ALL=1 ;;
g) generate=1 ;;
h) show_help ;;
i) REPLACE_ALL=0 ;;
- I) includes="$includes $OPTARG" ;;
+ I) includes="$(append_variable "$includes" "$OPTARG")" ;;
k) run_hooks=1 ;;
K) run_hooks=0 ;;
q) verbosity=$(($verbosity - 1)) ;;
- t) arg_tags="$arg_tags $OPTARG" ;;
- S) symlink_dirs="$symlink_dirs $OPTARG";;
- s) never_symlink_dirs="$never_symlink_dirs $OPTARG";;
- U) undotted="$undotted $OPTARG";;
- u) never_undotted="$never_undotted $OPTARG";;
+ t) arg_tags="$(append_variable "$arg_tags" "$OPTARG")" ;;
+ S) symlink_dirs="$(append_variable "$symlink_dirs" "$OPTARG")" ;;
+ s) never_symlink_dirs="$(append_variable "$never_symlink_dirs" "$OPTARG")";;
+ U) undotted="$(append_variable "$undotted" "$OPTARG")" ;;
+ u) never_undotted="$(append_variable "$never_undotted" "$OPTARG")" ;;
v) verbosity=$(($verbosity + 1)) ;;
V) version=1 ;;
- x) excludes="$excludes $OPTARG" ;;
+ x) excludes="$(append_variable "$excludes" "$OPTARG")" ;;
?) show_help 64 ;;
esac
done
@@ -261,31 +261,31 @@ handle_command_line() {
done
for tag in $tags; do
- LS_ARGS="$LS_ARGS -t $tag"
+ LS_ARGS="$LS_ARGS -t \"$tag\""
done
- for dotfiles_dir in $DOTFILES_DIRS; do
- LS_ARGS="$LS_ARGS -d $dotfiles_dir"
+ for dotfiles_dir in "$DOTFILES_DIRS"; do
+ LS_ARGS="$LS_ARGS -d \"$dotfiles_dir\""
done
- for exclude in $excludes; do
- LS_ARGS="$LS_ARGS -x $exclude"
+ for exclude in "$excludes"; do
+ LS_ARGS="$LS_ARGS -x \"$exclude\""
done
- for include in $includes; do
- LS_ARGS="$LS_ARGS -I $include"
+ for include in "$includes"; do
+ LS_ARGS="$LS_ARGS -I \"$include\""
done
- for symlink_dir in $symlink_dirs; do
- LS_ARGS="$LS_ARGS -S $symlink_dir"
+ for symlink_dir in "$symlink_dirs"; do
+ LS_ARGS="$LS_ARGS -S \"$symlink_dir\""
done
- for never_symlink_dir in $never_symlink_dirs; do
- LS_ARGS="$LS_ARGS -s $never_symlink_dir"
+ for never_symlink_dir in "$never_symlink_dirs"; do
+ LS_ARGS="$LS_ARGS -s \"$never_symlink_dir\""
done
- for undot in $undotted; do
- LS_ARGS="$LS_ARGS -U $undot"
+ for undot in "$undotted"; do
+ LS_ARGS="$LS_ARGS -U \"$undot\""
done
- for never_undot in $never_undotted; do
- LS_ARGS="$LS_ARGS -u $never_undot"
+ for never_undot in "$never_undotted"; do
+ LS_ARGS="$LS_ARGS -u \"$never_undot\""
done
- LS_ARGS="$LS_ARGS -B $hostname $files"
+ LS_ARGS="$LS_ARGS -B \"$hostname\" $files"
$DEBUG "LS_ARGS: $LS_ARGS"
}
@@ -297,7 +297,7 @@ handle_command_line "$@"
run_hooks pre up
-dests_and_srcs="$(lsrc $LS_ARGS)"
+dests_and_srcs="$(eval "lsrc $LS_ARGS")"
saved_ifs="$IFS"
IFS='