Change make_path_safe to allow single dot relative imports, but no dots anywhere else. Added new unit tests for this.

This commit is contained in:
Beth Probert 2026-03-06 14:07:07 +00:00
parent 713df248ff
commit e5429d6cda
2 changed files with 37 additions and 1 deletions

View file

@ -137,9 +137,23 @@ def make_path_safe(unsafe_path_string: str) -> str:
else _POSIX_UNSAFE_PATTERN else _POSIX_UNSAFE_PATTERN
) )
for component in components: for i, component in enumerate(components):
if component in ("/", "\\"): if component in ("/", "\\"):
sanitised_components.append(component) sanitised_components.append(component)
elif component == ".":
# Only allow '.' if its the very first
# element and the next element is a separator.
# This allows for relative paths like "./file"
# but not "file./file"
is_first = i == 0
next_to_sep = (i + 1 < len(components)) and (
components[i + 1] in ("/", "\\")
)
if is_first and next_to_sep:
sanitised_components.append(component)
else:
sanitised_components.append("_")
elif component: elif component:
# 1. Strip trailing dots and spaces # 1. Strip trailing dots and spaces
# 2. Apply unsafe character regex # 2. Apply unsafe character regex

View file

@ -79,8 +79,30 @@ def test_make_path_safe_trailing_in_components():
assert make_path_safe("path /to. /file ") == "path/to/file" assert make_path_safe("path /to. /file ") == "path/to/file"
assert make_path_safe("path./to /file.") == "path/to/file" assert make_path_safe("path./to /file.") == "path/to/file"
# Allow dots at the start of the path
# As this is common for hidden files on POSIX and relative paths
# And is the configuration in the manual and simulation config
# json files.
assert make_path_safe("./path/to/file") == "./path/to/file"
assert make_path_safe("./path./to /file.") == "./path/to/file"
assert make_path_safe("./openflexure/data/") == "./openflexure/data/"
def test_make_path_safe_separators(): def test_make_path_safe_separators():
"""Test that separators are preserved and components sanitised.""" """Test that separators are preserved and components sanitised."""
assert make_path_safe("a/b\\c") == "a/b\\c" assert make_path_safe("a/b\\c") == "a/b\\c"
assert make_path_safe("a./b /c.") == "a/b/c" assert make_path_safe("a./b /c.") == "a/b/c"
def test_make_path_safe_relative():
"""Test that relative path components are preserved.
We only allow relative paths with one dot, and at the beginning of the path,
to avoid issues with paths like "file./file" or "file../file
"""
assert make_path_safe("./openflexure/data/") == "./openflexure/data/"
assert make_path_safe("../openflexure/data/") == "_/openflexure/data/"
assert make_path_safe("path/./to/file") == "path/_/to/file"
assert make_path_safe("path/../to/file") == "path/_/to/file"
assert make_path_safe(".") == "_"
assert make_path_safe("..") == "_"