Merge pull request #9598 from ThomasWaldmann/slashdot-root-master

Fix slashdot hack excluding source directory metadata, fixes #9534
This commit is contained in:
TW 2026-05-12 22:43:41 +02:00 committed by GitHub
commit 7b60edd0c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 3 deletions

View file

@ -1277,12 +1277,16 @@ class FilesystemObjectProcessors:
def create_helper(self, path, st, status=None, hardlinkable=True, strip_prefix=None):
if strip_prefix is not None:
assert not path.endswith("/")
if strip_prefix.startswith(path + "/"):
if path + "/" == strip_prefix:
# this is the directory the slashdot hack points to - archive it as the root.
path = "."
elif strip_prefix.startswith(path + "/"):
# still on a directory level that shall be stripped - do not create an item for this!
yield None, "x", False, None
return
# adjust path, remove stripped directory levels
path = path.removeprefix(strip_prefix)
else:
# adjust path, remove stripped directory levels
path = path.removeprefix(strip_prefix)
sanitized_path = remove_dotdot_prefixes(path)
item = Item(path=sanitized_path)

View file

@ -1002,6 +1002,25 @@ def test_create_dotslash_hack(archivers, request):
assert "secondB/thirdB" in output
def test_create_dotslash_hack_root_metadata(archivers, request):
"""Test that the slashdot hack archives the source directory metadata as the archive root."""
archiver = request.getfixturevalue(archivers)
os.makedirs(os.path.join(archiver.input_path, "first", "subdir"))
create_regular_file(archiver.input_path, "first/file1", contents=b"hello")
cmd(archiver, "repo-create", RK_ENCRYPTION)
cmd(archiver, "create", "test", "input/first/./") # slashdot hack
output = cmd(archiver, "list", "test")
# the root directory "." must be in the archive (this was the bug in #9534).
lines = output.splitlines()
assert lines[0].endswith(" .")
# children of the slashdot target must be archived.
assert "subdir" in output
assert "file1" in output
# parent directories must NOT be in the archive.
assert "input" not in output
assert "first" not in output
def test_log_json(archivers, request):
archiver = request.getfixturevalue(archivers)
create_test_files(archiver.input_path)