From 29adb65d398a88b76c6994fe9ddffac02a349e59 Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Wed, 14 Jan 2026 19:15:42 +0100 Subject: [PATCH] Project.is_path_in_project: Allow symlinks pointing outside the project directory to be accessed It is reasonable to assume that symlinks point to relevant project content (instead of disallowing access). Resolves #936 --- src/serena/project.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/serena/project.py b/src/serena/project.py index 968ad545..90a2a33e 100644 --- a/src/serena/project.py +++ b/src/serena/project.py @@ -230,15 +230,21 @@ class Project(ToStringMixin): def is_path_in_project(self, path: str | Path) -> bool: """ Checks if the given (absolute or relative) path is inside the project directory. - Note that even relative paths may be outside if they contain ".." or point to symlinks. - """ - path = Path(path) - _proj_root = Path(self.project_root) - if not path.is_absolute(): - path = _proj_root / path - path = path.resolve() - return path.is_relative_to(_proj_root) + Note: This is intended to catch cases where ".." segments would lead outside of the project directory, + but we intentionally allow symlinks, as the assumption is that they point to relevant project files. + """ + if not os.path.isabs(path): + path = os.path.join(self.project_root, path) + + # collapse any ".." or "." segments (purely lexically) + path = os.path.normpath(path) + + try: + return os.path.commonpath([self.project_root, path]) == self.project_root + except ValueError: + # occurs, in particular, if paths are on different drives on Windows + return False def relative_path_exists(self, relative_path: str) -> bool: """