From cbc346b279b5c08b281c9901b994a58eb037a60d Mon Sep 17 00:00:00 2001 From: Edd Salkield Date: Sat, 18 Jan 2020 18:40:45 +0000 Subject: 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. --- bin/lsrc.in | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'bin/lsrc.in') diff --git a/bin/lsrc.in b/bin/lsrc.in index 6fb6162..eed4c0a 100755 --- a/bin/lsrc.in +++ b/bin/lsrc.in @@ -166,7 +166,7 @@ dotfiles_dir_excludes() { $DEBUG "dotfiles_dir_excludes $dotfiles_dir" $DEBUG " with excludes: $excludes" - for exclude in $excludes; do + for exclude in "$excludes"; do if echo "$exclude" | grep ':' >/dev/null; then dotfiles_dir_pat="$(echo "$exclude" | sed 's/:.*//')" file_glob="$(echo "$exclude" | sed 's/.*://')" @@ -259,17 +259,17 @@ handle_command_line() { case "$opt" in F) show_sigils=1;; h) show_help ;; - I) includes="$includes $OPTARG";; - t) arg_tags="$arg_tags $OPTARG";; + I) includes="$(append_variable "$includes" "$OPTARG")" ;; + t) arg_tags="$(append_variable "$arg_tags" "$OPTARG")" ;; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; - d) dotfiles_dirs="$dotfiles_dirs $OPTARG";; + d) dotfiles_dirs="$(append_variable "$dotfiles_dirs" "$OPTARG")" ;; V) version=1;; - x) excludes="$excludes $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";; + x) excludes="$(append_variable "$excludes" "$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")" ;; B) hostname="$OPTARG";; ?) show_help 64 ;; esac -- cgit v1.2.3 From 458d55474ed3965a87ff414bbc07d85a3b300bfb Mon Sep 17 00:00:00 2001 From: Mat M Date: Tue, 3 Dec 2019 23:34:09 +0100 Subject: Fix #237 Fix $ sigil for lsrc -F Add test --- NEWS.md.in | 1 + bin/lsrc.in | 2 +- test/lsrc-sigils.t | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'bin/lsrc.in') diff --git a/NEWS.md.in b/NEWS.md.in index 4461a2f..859f2a8 100644 --- a/NEWS.md.in +++ b/NEWS.md.in @@ -1,5 +1,6 @@ rcm (@PACKAGE_VERSION@) unstable; urgency=low + * BUGFIX: Fix #237 - $ for symlinked dirs with lsrc -F (Mathias Michel). * Fix #144 and more: all symlinks in input are rejected (Mat M) -- Mike Burns Fri, 13 Jul 2018 14:12:00 -0500 diff --git a/bin/lsrc.in b/bin/lsrc.in index eed4c0a..7a531f0 100755 --- a/bin/lsrc.in +++ b/bin/lsrc.in @@ -144,7 +144,7 @@ handle_file() { elif is_excluded "$dotfiles_subdir/$file" "$exclude_file_globs" "$include_file_globs"; then $VERBOSE "skipping excluded file $file" elif [ -d "$file" ] && is_excluded "$dotfiles_subdir/$file" "$symlink_dirs_file_globs" "$mk_dirs_file_globs"; then - show_file "$file" "$dest_dir" "$dotfiles_dir" "$dotfiles_subdir" $dotted + show_file "$file" "$dest_dir" "$dotfiles_dir" "$dotfiles_subdir" $dotted "$symlink_dirs_file_globs" elif [ -d "$file" ]; then show_dir "$file" "$dest_dir" "$dotfiles_dir" "$dotfiles_subdir" $dotted "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" "$mk_dirs_file_globs" else diff --git a/test/lsrc-sigils.t b/test/lsrc-sigils.t index 98573b2..9bdc82d 100644 --- a/test/lsrc-sigils.t +++ b/test/lsrc-sigils.t @@ -14,3 +14,12 @@ Should print X for files in COPY_ALWAYS $ COPY_ALWAYS=copy lsrc -F /*/.copy:/*/.dotfiles/copy:X (glob) /*/.example:/*/.dotfiles/example:@ (glob) + +Should print $ for directory links + + $ mkdir .dotfiles/folder + + $ SYMLINK_DIRS=folder COPY_ALWAYS=copy lsrc -F + /*/.copy:/*/.dotfiles/copy:X (glob) + /*/.example:/*/.dotfiles/example:@ (glob) + /*/.folder:/*/.dotfiles/folder:$ (glob) -- cgit v1.2.3