Skip to content

Commit 0a137e4

Browse files
authored
fix: missing edge case: is_safe_path with relative paths
1 parent b7cc5c0 commit 0a137e4

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

tests/test_model_management.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,3 +1995,54 @@ def test_blocks_parent_traversal_hardlink_target(self, tmp_path):
19951995
self._member("link", is_reg=False, is_lnk=True, linkname="../outside.txt"),
19961996
str(tmp_path),
19971997
)
1998+
1999+
2000+
class TestIsWithinDir:
2001+
"""Tests for _is_within_dir static method."""
2002+
2003+
def test_is_within_dir_absolute_paths_success(self):
2004+
"""Test _is_within_dir with absolute paths that resolve correctly."""
2005+
base = "/tmp/base"
2006+
candidate = "/tmp/base/sub/file.txt"
2007+
assert ModelManagement._is_within_dir(base, candidate) is True
2008+
2009+
def test_is_within_dir_absolute_paths_failure(self):
2010+
"""Test _is_within_dir with absolute paths that are outside the base."""
2011+
base = "/tmp/base"
2012+
candidate = "/tmp/other/file.txt"
2013+
assert ModelManagement._is_within_dir(base, candidate) is False
2014+
2015+
def test_is_within_dir_relative_paths_success(self):
2016+
"""Test _is_within_dir with relative paths that resolve inside the base."""
2017+
# abspath will resolve relative to the current working directory
2018+
base = "cache"
2019+
candidate = "cache/sub/file.txt"
2020+
assert ModelManagement._is_within_dir(base, candidate) is True
2021+
2022+
def test_is_within_dir_relative_paths_failure(self):
2023+
"""Test _is_within_dir with relative paths that resolve outside the base."""
2024+
base = "cache"
2025+
candidate = "cache/../../evil.txt"
2026+
assert ModelManagement._is_within_dir(base, candidate) is False
2027+
2028+
def test_is_within_dir_sibling_directories(self):
2029+
"""Test _is_within_dir with sibling directories sharing a prefix."""
2030+
base = "/tmp/cache"
2031+
candidate = "/tmp/cache-evil/file.txt"
2032+
assert ModelManagement._is_within_dir(base, candidate) is False
2033+
2034+
def test_is_within_dir_trailing_separators(self):
2035+
"""Test _is_within_dir with trailing separators."""
2036+
base = "/tmp/cache/"
2037+
candidate = "/tmp/cache/file.txt"
2038+
assert ModelManagement._is_within_dir(base, candidate) is True
2039+
2040+
def test_is_within_dir_same_path(self):
2041+
"""Test _is_within_dir when base and candidate are the same."""
2042+
path = "/tmp/cache"
2043+
assert ModelManagement._is_within_dir(path, path) is True
2044+
2045+
def test_is_within_dir_different_drives(self):
2046+
"""Test _is_within_dir when paths are on different drives (Windows)."""
2047+
with patch("os.path.commonpath", side_effect=ValueError):
2048+
assert ModelManagement._is_within_dir("C:\\base", "D:\\base") is False

0 commit comments

Comments
 (0)