Skip to content

WIP Improve handling of challenging file names when 'core.quotePath=true' #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions tests/_test_helper.bash
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,22 @@ function nuke_git_repo {
function cleanup_all {
nuke_git_repo
rm $BATS_TEST_DIRNAME/.gitattributes
rm $BATS_TEST_DIRNAME/sensitive_file
rm -f $BATS_TEST_DIRNAME/sensitive_file
}

function init_transcrypt {
$BATS_TEST_DIRNAME/../transcrypt --cipher=aes-256-cbc --password=abc123 --yes
}

function encrypt_named_file {
filename=$1
filename="$1"
content=$2
if [ "$content" ]; then
echo "$content" > $filename
echo "$content" > "$filename"
fi
echo "$filename filter=crypt diff=crypt merge=crypt" >> .gitattributes
git add .gitattributes $filename
git commit -m "Encrypt file $filename"
echo "\"$filename\" filter=crypt diff=crypt merge=crypt" >> .gitattributes
git add .gitattributes "$filename"
run git commit -m "Encrypt file \"$filename\""
}

function setup {
Expand Down
43 changes: 43 additions & 0 deletions tests/test_crypt.bats
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,46 @@ function check_repo_is_clean {
[ "${lines[0]}" != "$SECRET_CONTENT" ]
[ "${lines[0]}" = "$SECRET_CONTENT_ENC" ]
}

@test "crypt: handle challenging file names when 'core.quotePath=true'" {
# Set core.quotePath=true which is the Git default prior to encrypting a
# file with non-ASCII characters and spaces in the name, to confirm
# transcrypt can handle the file properly.
# For info about the 'core.quotePath' setting see
# https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath
git config --local --add core.quotePath true

FILENAME="Mig – røve" # Danish
SECRET_CONTENT_ENC="U2FsdGVkX19Fp9SwTyQ+tz1OgHNIN0OJ+6sMgHIqPMzfdZ6rZ2iVquS293WnjJMx"

encrypt_named_file "$FILENAME" "$SECRET_CONTENT"
[[ "${lines[0]}" = *"Encrypt file \"$FILENAME\"" ]]

# Working copy is decrypted
run cat "$FILENAME"
[ "$status" -eq 0 ]
[ "${lines[0]}" = "$SECRET_CONTENT" ]

# Git internal copy is encrypted
run git show HEAD:"$FILENAME" --no-textconv
[ "$status" -eq 0 ]
[ "${lines[0]}" = "$SECRET_CONTENT_ENC" ]

# transcrypt --show-raw shows encrypted content
run ../transcrypt --show-raw "$FILENAME"
[ "$status" -eq 0 ]
[ "${lines[0]}" = "==> $FILENAME <==" ]
[ "${lines[1]}" = "$SECRET_CONTENT_ENC" ]

# git ls-crypt lists encrypted file
run git ls-crypt
[ "$status" -eq 0 ]
[ "${lines[0]}" = "$FILENAME" ]

# transcrypt --list lists encrypted file"
run ../transcrypt --list
[ "$status" -eq 0 ]
[ "${lines[0]}" = "$FILENAME" ]

rm "$FILENAME"
}
2 changes: 1 addition & 1 deletion tests/test_init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ SETUP_SKIP_INIT_TRANSCRYPT=1
[ `git config --get diff.crypt.binary` = "true" ]
[ `git config --get merge.renormalize` = "true" ]

[[ `git config --get alias.ls-crypt` = "!git ls-files"* ]]
[[ `git config --get alias.ls-crypt` = "!git -c core.quotePath=false ls-files"* ]]
}

@test "init: show details for --display" {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_pre_commit.bats
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ load $BATS_TEST_DIRNAME/_test_helper.bash
run git log --format=oneline
[ "$status" -eq 0 ]
[[ "${lines[0]}" = *"Added more" ]]
[[ "${lines[1]}" = *"Encrypt file sensitive_file" ]]
[[ "${lines[1]}" = *"Encrypt file \"sensitive_file\"" ]]
}

@test "pre-commit: reject commit of encrypted file with unencrypted content" {
Expand Down
12 changes: 7 additions & 5 deletions transcrypt
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ save_helper_hooks() {
cat <<-'EOF' >"$pre_commit_hook_installed"
#!/usr/bin/env bash
# Transcrypt pre-commit hook: fail if secret file in staging lacks the magic prefix "Salted" in B64
for secret_file in $(git ls-files | git check-attr --stdin filter | awk 'BEGIN { FS = ":" }; /crypt$/{ print $1 }'); do
IFS=$'\n'
for secret_file in $(git -c core.quotePath=false ls-files | git -c core.quotePath=false check-attr --stdin filter | awk 'BEGIN { FS = ":" }; /crypt$/{ print $1 }'); do
# Get prefix of raw file in Git's index using the :FILENAME revision syntax
firstbytes=$(git show :$secret_file | head -c 8)
# An empty file does not need to be, and is not, encrypted
Expand All @@ -401,6 +402,7 @@ save_helper_hooks() {
exit 1
fi
done
unset IFS
EOF

# Activate hook by copying it to the pre-commit script name, if safe to do so
Expand Down Expand Up @@ -455,7 +457,7 @@ save_configuration() {
git config merge.crypt.name 'Merge transcrypt secret files'

# add a git alias for listing encrypted files
git config alias.ls-crypt "!git ls-files | git check-attr --stdin filter | awk 'BEGIN { FS = \":\" }; /crypt$/{ print \$1 }'"
git config alias.ls-crypt "!git -c core.quotePath=false ls-files | git -c core.quotePath=false check-attr --stdin filter | awk 'BEGIN { FS = \":\" }; /crypt$/{ print \$1 }'"
}

# display the current configuration settings
Expand Down Expand Up @@ -622,7 +624,7 @@ uninstall_transcrypt() {
list_files() {
if [[ $IS_BARE == 'false' ]]; then
cd "$REPO" || die 1 'could not change into the "%s" directory' "$REPO"
git ls-files | git check-attr --stdin filter | awk 'BEGIN { FS = ":" }; /crypt$/{ print $1 }'
git -c core.quotePath=false ls-files | git -c core.quotePath=false check-attr --stdin filter | awk 'BEGIN { FS = ":" }; /crypt$/{ print $1 }'
fi
}

Expand All @@ -631,8 +633,8 @@ show_raw_file() {
if [[ -f $show_file ]]; then
# ensure the file is currently being tracked
local escaped_file=${show_file//\//\\\/}
if git ls-files --others -- "$show_file" | awk "/${escaped_file}/{ exit 1 }"; then
file_paths=$(git ls-tree --name-only --full-name HEAD "$show_file")
if git -c core.quotePath=false ls-files --others -- "$show_file" | awk "/${escaped_file}/{ exit 1 }"; then
file_paths=$(git -c core.quotePath=false ls-tree --name-only --full-name HEAD "$show_file")
else
die 1 'the file "%s" is not currently being tracked by git' "$show_file"
fi
Expand Down