From f07741a8d5a820c39b8d3349b6e84c8fd3b67b59 Mon Sep 17 00:00:00 2001 From: redxef Date: Wed, 7 Jun 2023 21:53:14 +0200 Subject: [PATCH] Add ssh-docker test, fix filename escaping when using ssh. --- tarback.sh | 22 ++++++++++++++++++++-- test.sh | 4 ++++ tests/common.sh | 5 ++++- tests/test-000-simple.sh | 10 ++++++---- tests/test-001-ssh.sh | 10 ++++++---- tests/test-002-docker.sh | 10 ++++++---- tests/test-003-ssh-docker.sh | 31 +++++++++++++++++++++++++++++++ 7 files changed, 77 insertions(+), 15 deletions(-) create mode 100755 tests/test-003-ssh-docker.sh diff --git a/tarback.sh b/tarback.sh index 4caf9e4..8501c5e 100755 --- a/tarback.sh +++ b/tarback.sh @@ -64,6 +64,24 @@ _transform_remote() { echo "$r" } +_transform_argument_ssh() { + command_name="$(echo "$TARBACK_REMOTE" | awk '{print $1}')" + if echo "$command_name" | grep -q 'ssh'; then + echo "'$(printf '%s' "$1" | sed "s/'/'\\\\''/g")'" + else + echo "$1" + fi +} + +_transform_argument() { + a="$1" + for t in _transform_argument_ssh; do + [ -z "$t" ] && continue # skip empty transformers + a="$("$t" "$a")" + done + echo "$a" +} + _create() { # $1 ... src # $2 ... dst @@ -75,7 +93,7 @@ _create() { tarback_tar_create_command="$TARBACK_TAR_CREATE_COMMAND_FILE" fi tarback_tar_create_command="$(_transform_remote "$tarback_tar_create_command")" - $TARBACK_REMOTE sh -c "$tarback_tar_create_command" - "$src" \ + $TARBACK_REMOTE sh -c "$tarback_tar_create_command" - "$(_transform_argument_ssh "$src")" \ | $TARBACK_COMPRESSION \ | $TARBACK_SPLIT "$dst" } @@ -95,7 +113,7 @@ _restore() { tarback_tar_extract_command="$(_transform_remote "$tarback_tar_extract_command")" $TARBACK_MERGE "$src"* \ | $TARBACK_COMPRESSION --decompress --stdout \ - | $TARBACK_REMOTE sh -c "$tarback_tar_extract_command" - "$dst" + | $TARBACK_REMOTE sh -c "$tarback_tar_extract_command" - "$(_transform_argument_ssh "$dst")" } restore() { diff --git a/test.sh b/test.sh index 46d3750..2cea390 100755 --- a/test.sh +++ b/test.sh @@ -2,6 +2,7 @@ set -eu +early_return="${TARBACK_TEST_EARLY_RETURN:-false}" failed=0 for f in ./tests/test-*.sh; do printf '%s' "Running test $f ... " @@ -10,6 +11,9 @@ for f in ./tests/test-*.sh; do else failed=$((failed+1)) echo "failed" + if "$early_return"; then + break + fi fi done diff --git a/tests/common.sh b/tests/common.sh index a3af51e..f7801f8 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -5,6 +5,9 @@ create_directories() { mkdir -p "$workdir/source" mkdir -p "$workdir/dest" mkdir -p "$workdir/restore" - echo 'Hello World!' > "$workdir/source/hello_world.txt" + # generate a filename with every possible byte in it to test + # escaping, the only character not included is `/` since that is + # illegal for filenames (obviously) + echo 'Hello World!' > "$workdir/source/$(for i in $(seq 0 255); do printf '%x' "$i" | xxd -r -p; done | tr -d '/')" echo "$workdir" } diff --git a/tests/test-000-simple.sh b/tests/test-000-simple.sh index b9dafde..f33490e 100755 --- a/tests/test-000-simple.sh +++ b/tests/test-000-simple.sh @@ -13,15 +13,17 @@ rm -rf "$workdir" # archive single file workdir="$(create_directories)" -./tarback.sh create "$workdir/source/hello_world.txt" "$workdir/dest/source.tar.xz" -./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/hello_world.txt" +filename="$(basename "$(find "$workdir/source" -type f)")" +./tarback.sh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # split archive workdir="$(create_directories)" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh create "$workdir/source/hello_world.txt" "$workdir/dest/source.tar.xz" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/hello_world.txt" +filename="$(basename "$(find "$workdir/source" -type f)")" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" [ "$(ls -1 "$workdir/dest/"*.part* | wc -l)" -gt 1 ] rm -rf "$workdir" diff --git a/tests/test-001-ssh.sh b/tests/test-001-ssh.sh index 42e3c3b..4bc13cf 100755 --- a/tests/test-001-ssh.sh +++ b/tests/test-001-ssh.sh @@ -15,15 +15,17 @@ rm -rf "$workdir" # archive single file workdir="$(create_directories)" -./tarback.sh create "$workdir/source/hello_world.txt" "$workdir/dest/source.tar.xz" -./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/hello_world.txt" +filename="$(basename "$(find "$workdir/source" -type f)")" +./tarback.sh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # split archive workdir="$(create_directories)" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh create "$workdir/source/hello_world.txt" "$workdir/dest/source.tar.xz" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/hello_world.txt" +filename="$(basename "$(find "$workdir/source" -type f)")" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" [ "$(ls -1 "$workdir/dest/"*.part* | wc -l)" -gt 1 ] rm -rf "$workdir" diff --git a/tests/test-002-docker.sh b/tests/test-002-docker.sh index da25aae..e69c38e 100755 --- a/tests/test-002-docker.sh +++ b/tests/test-002-docker.sh @@ -13,15 +13,17 @@ rm -rf "$workdir" # archive single file workdir="$(create_directories)" -./tarback.sh -p docker create "$workdir/source/hello_world.txt" "$workdir/dest/source.tar.xz" -./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/hello_world.txt" +filename="$(basename "$(find "$workdir/source" -type f)")" +./tarback.sh -p docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # split archive workdir="$(create_directories)" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker create "$workdir/source/hello_world.txt" "$workdir/dest/source.tar.xz" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/hello_world.txt" +filename="$(basename "$(find "$workdir/source" -type f)")" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" [ "$(ls -1 "$workdir/dest/"*.part* | wc -l)" -gt 1 ] rm -rf "$workdir" diff --git a/tests/test-003-ssh-docker.sh b/tests/test-003-ssh-docker.sh new file mode 100755 index 0000000..2746f82 --- /dev/null +++ b/tests/test-003-ssh-docker.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +set -eu + +. ./tests/common.sh + +export TARBACK_REMOTE='ssh localhost' + +# archive whole directory +workdir="$(create_directories)" +./tarback.sh -p docker create "$workdir/source" "$workdir/dest/source.tar.xz" +./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore" +diff "$workdir/source" "$workdir/restore" +rm -rf "$workdir" + +# archive single file +workdir="$(create_directories)" +filename="$(basename "$(find "$workdir/source" -type f)")" +./tarback.sh -p docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" +diff "$workdir/source" "$workdir/restore" +rm -rf "$workdir" + +# split archive +workdir="$(create_directories)" +filename="$(basename "$(find "$workdir/source" -type f)")" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" +diff "$workdir/source" "$workdir/restore" +[ "$(ls -1 "$workdir/dest/"*.part* | wc -l)" -gt 1 ] +rm -rf "$workdir"