RigShare 1.3.1: refuse folder paths outside the workspace (Windows)

This commit is contained in:
Edouard Durand
2026-10-08 08:33:04 +00:00
parent d68307cde4
commit c6ded00173
8 changed files with 260 additions and 13 deletions
+52
View File
@@ -131,3 +131,55 @@ def test_rename_user_moves_private_folder(ws):
ws.rename_user("alice", "alicia")
assert os.path.exists(os.path.join(ws.root, "users", "alicia", "keep.json"))
assert ws.folders["shared/Team"]["owner"] == "alicia"
@pytest.mark.parametrize("raw", ["C:/models", "C:", "a/D:x/b", r"..\..\x", "c%3A%5Cmodels"])
def test_norm_drops_drive_segments(raw):
assert ":" not in norm(raw) and ".." not in norm(raw).split("/")
@pytest.mark.parametrize("bad", ["C:/models", "C:", "..", "a/../..", "x:y"])
def test_safe_join_refuses_escapes(ws, bad):
from rigshare_core.workspace import safe_join
with pytest.raises(PermissionError):
safe_join(ws.root, bad)
def test_folder_ops_cannot_leave_the_workspace(ws, tmp_path):
outside = tmp_path / "models"
outside.mkdir()
(outside / "keep.txt").write_text("x")
for bad in (str(outside), "C:" + str(outside)[2:], "shared/C:evil"):
with pytest.raises(PermissionError):
ws.delete_folder(bad)
with pytest.raises(PermissionError):
ws.rename_folder(bad, "renamed")
assert (outside / "keep.txt").exists()
@pytest.mark.parametrize("raw", ["users./bob/a.json", "users /bob", "USERS~1/bob", "users/bob./a.json"])
def test_norm_drops_windows_aliases(raw):
if os.name != "nt" and ("." in raw.split("/")[0] or " " in raw.split("/")[0]):
pytest.skip("trailing dots and spaces only alias on Windows")
assert "~1" not in norm(raw)
@pytest.mark.skipif(os.name != "nt", reason="case-insensitive filesystem")
def test_case_variants_cannot_bypass_private_folders(ws):
touch(ws, "users/alice/a.json")
assert norm("Users/Alice/a.json") == "users/alice/a.json"
assert norm("Workflows/USERS/ALICE") == "workflows/users/alice"
assert ws.role(norm("USERS/alice/a.json"), "user", "bob", EDITOR) is None
def test_name_rules():
from rigshare_core.workspace import FOLDER_NAME_RE
from rigshare_core.store import USERNAME_RE
for bad in ("con", "NUL", "com1.txt", "art.", "art ", "bad\n"):
assert not FOLDER_NAME_RE.match(bad), bad
for bad in ("..", "bob.", ".bob", "con", "aux", "ab\n", "a"):
assert not USERNAME_RE.match(bad), bad
for ok in ("Art (v2)", "a", "my-folder"):
assert FOLDER_NAME_RE.match(ok), ok
for ok in ("bob", "al.ice", "x_y-z", "ab"):
assert USERNAME_RE.match(ok), ok