fix: check_modified uses lexical containment, explicit is_symlink check

- check_modified() no longer calls _validate_rel_path (which resolves
  symlinks); uses lexical checks (is_absolute, '..' in parts) instead
- is_symlink() checked before is_file() so symlinks to files are still
  treated as modified
- Fixed templates_dir() docstring to match actual behavior
This commit is contained in:
Manfred Riem
2026-03-31 10:16:47 -05:00
parent 07a7ad8757
commit 8168306467
2 changed files with 9 additions and 8 deletions

View File

@@ -87,8 +87,8 @@ class IntegrationBase(ABC):
def templates_dir(self) -> Path:
"""Return the path to this integration's bundled templates.
By convention, templates live in a ``templates/`` subdirectory next
to the integration's ``__init__.py``.
By convention, templates live in a ``templates/`` subdirectory
next to the file where the integration class is defined.
"""
import inspect

View File

@@ -113,14 +113,15 @@ class IntegrationManifest:
"""Return relative paths of tracked files whose content changed on disk."""
modified: list[str] = []
for rel, expected_hash in self._files.items():
try:
abs_path = _validate_rel_path(Path(rel), self.project_root)
except ValueError:
rel_path = Path(rel)
# Skip paths that are absolute or attempt to escape the project root
if rel_path.is_absolute() or ".." in rel_path.parts:
continue
if not abs_path.exists():
abs_path = self.project_root / rel_path
if not abs_path.exists() and not abs_path.is_symlink():
continue
# Treat non-regular-files (directories, symlinks) as modified
if not abs_path.is_file():
# Treat symlinks and non-regular-files as modified
if abs_path.is_symlink() or not abs_path.is_file():
modified.append(rel)
continue
if _sha256(abs_path) != expected_hash: