Skip to content

Commit

Permalink
Fix bug when linking files that contain printf conversion specifications
Browse files Browse the repository at this point in the history
The fix leads to a more robust way to loop through repository files
by using the -z flag of ls-files. It has been available
since git 1.5.0, so no dep requirement changes are necessary.
(See https://github.com/git/git/blob/v1.5.0/builtin-ls-files.c#L341-L344)

Reported in #223 by @ncallister. Thank you Nathan :-)
  • Loading branch information
andsens committed Jul 26, 2024
1 parent 3b77a58 commit e465842
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 8 deletions.
11 changes: 4 additions & 7 deletions lib/commands/link.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ get_repo_files() {
root=$(cd "$1" && pwd -P)
(
local path
while IFS= read -d $'\n' -r path; do
while IFS= read -d $'\0' -r path; do
# Remove quotes from ls-files
# (used when there are newlines in the path)
path=${path/#\"/}
Expand All @@ -104,23 +104,20 @@ get_repo_files() {
# Remove the home/ part
path=${path/#home\//}
# Print the file path (NUL separated because \n can be used in filenames)
# Disable SC2059, using %s messes with the filename
# shellcheck disable=SC2059
printf "$path\0"
printf "%s\0" "$path"
# Get the path of all the parent directories
# up to the repo root.
while true; do
path=$(dirname "$path")
# If path is '.' we're done
[[ $path == '.' ]] && break
# Print the path
# shellcheck disable=SC2059
printf "$path\0"
printf "%s\0" "$path"
done
# Enter the repo, list the repo root files in home
# and do the same for any submodules
done < <(cd "$root" &&
git ls-files 'home/' &&
git ls-files -z 'home/' &&
git submodule --quiet foreach --recursive \
"$homeshick/lib/submodule_files.sh \"$root\" \"\$toplevel\" \"\$path\"")
# Unfortunately we have to use an external script for `git submodule foreach'
Expand Down
2 changes: 1 addition & 1 deletion lib/submodule_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ if [[ $repo =~ ^home ]]; then
cd "$toplevel/$path"
# List the files and prefix every line
# with the relative repo path
git ls-files | sed "s#^#${repo//#/\\#}/#"
git ls-files -z | sed -z "s#^#${repo//#/\\#}/#"
fi
2 changes: 2 additions & 0 deletions test/fixtures/repo with spaces in name.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ fixture_repo_with_spaces_in_name() {
file␇☺"
git add ".crazy
file␇☺"
touch "%printf conver%sionchar%s %%"
git add "%printf conver%sionchar%s %%"

git commit -m 'Add file with newline and all kinds of crazy characters in the name'
}
Expand Down
7 changes: 7 additions & 0 deletions test/suites/link.bats
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ file␇☺"
file␇☺"
}

@test 'link file with printf conversion chars' {
castle 'repo with spaces in name'
homeshick --batch link 'repo with spaces in name'
stat "$HOME/%printf conver%sionchar%s %%"
test -f "$HOME/%printf conver%sionchar%s %%"
}

@test 'do not fail when linking file with newline' {
castle 'rc-files'
test_filename="filename
Expand Down

0 comments on commit e465842

Please sign in to comment.