Skip to content
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
6 changes: 6 additions & 0 deletions src/borg/helpers/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ def make_path_safe(path):
if "\\.." in path or "..\\" in path:
raise ValueError(f"unexpected '..' element in path {path!r}")

path = slashify(path)

if is_win32 and len(path) >= 2 and path[1] == ":":
# Handle drive letters: C:/path -> C/path
path = path[0].upper() + path[2:]

path = map_chars(path)

path = path.lstrip("/")
Expand Down
17 changes: 17 additions & 0 deletions src/borg/testsuite/helpers/fs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,23 @@ def test_invalid_make_path_safe(path):
make_path_safe(path)


def test_make_path_safe_win32_drive_letters(monkeypatch):
monkeypatch.setattr("borg.helpers.fs.is_win32", True)
# Basic drive letter
assert make_path_safe("C:\\Users") == "C/Users"
assert make_path_safe("C:\\Users\\test") == "C/Users/test"
# Lowercase drive letter -> Uppercase
assert make_path_safe("c:\\windows") == "C/windows"
# Relative path with backslashes
assert make_path_safe("foo\\bar") == "foo/bar"
# Just drive letter
assert make_path_safe("D:") == "D"
# Drive letter with forward slash
assert make_path_safe("E:/test") == "E/test"
# Mixed separators
assert make_path_safe("F:\\Mixed/Separators") == "F/Mixed/Separators"


def test_dir_is_tagged(tmpdir):
"""Test dir_is_tagged with both path-based and file descriptor-based operations."""

Expand Down