From 628b6ba45c52aa6d556ba5b1494d176ea32e38e2 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Thu, 26 Jun 2025 20:33:38 +0200 Subject: [PATCH] import-tar: fix the dotslash issue, add test --- src/borg/archive.py | 5 +++- src/borg/testsuite/archiver/tar_cmds_test.py | 28 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/borg/archive.py b/src/borg/archive.py index 5bf8faaec..c4b27d6a7 100644 --- a/src/borg/archive.py +++ b/src/borg/archive.py @@ -1518,8 +1518,11 @@ class TarfileObjectProcessors: def s_to_ns(s): return safe_ns(int(float(s) * 1e9)) + # if the tar has names starting with "./", normalize them like borg create also does. + # ./dir/file must become dir/file in the borg archive. + normalized_path = os.path.normpath(tarinfo.name) item = Item( - path=make_path_safe(tarinfo.name), + path=make_path_safe(normalized_path), mode=tarinfo.mode | type, uid=tarinfo.uid, gid=tarinfo.gid, diff --git a/src/borg/testsuite/archiver/tar_cmds_test.py b/src/borg/testsuite/archiver/tar_cmds_test.py index 36cd42bd4..88f9f74f4 100644 --- a/src/borg/testsuite/archiver/tar_cmds_test.py +++ b/src/borg/testsuite/archiver/tar_cmds_test.py @@ -211,6 +211,34 @@ def test_import_concatenated_tar_without_ignore_zeros(archivers, request): assert os.listdir("output") == ["file1"] +@requires_gnutar +def test_import_tar_with_dotslash_paths(archivers, request): + """Test that paths starting with './' are normalized during import-tar.""" + archiver = request.getfixturevalue(archivers) + # Create a simple directory structure + create_regular_file(archiver.input_path, "dir/file") + + # Create a tar file with paths starting with './' + with changedir("input"): + # Directly use a path that starts with './' + subprocess.check_call(["tar", "cf", "dotslash.tar", "./dir"]) + + # Verify the tar file contains paths with './' prefix + tar_content = subprocess.check_output(["tar", "tf", "dotslash.tar"]).decode() + assert "./dir" in tar_content + assert "./dir/file" in tar_content + + # Import the tar file into a Borg repository + cmd(archiver, "repo-create", "--encryption=none") + cmd(archiver, "import-tar", "dotslash", "input/dotslash.tar") + + # List the archive contents and verify no paths start with './' + output = cmd(archiver, "list", "--format={path}{NL}", "dotslash") + assert "./dir" not in output + assert "dir" in output + assert "dir/file" in output + + def test_roundtrip_pax_borg(archivers, request): archiver = request.getfixturevalue(archivers) create_test_files(archiver.input_path)