Skip to content

Commit 3b01246

Browse files
committed
fix CodeQL alert
1 parent 6d3bc5e commit 3b01246

1 file changed

Lines changed: 22 additions & 17 deletions

File tree

app/scenario_planning.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,28 @@ def _normalize_pack_id(value: Any) -> str:
3030
return re.sub(r"[^A-Za-z0-9_.-]", "", raw)
3131

3232

33+
def _resolve_workspace_path(candidate: Path) -> Path | None:
34+
try:
35+
workspace_root = WORKSPACE_ROOT.resolve()
36+
raw_path = candidate if candidate.is_absolute() else (workspace_root / candidate)
37+
resolved = raw_path.resolve(strict=False)
38+
resolved.relative_to(workspace_root)
39+
return resolved
40+
except (OSError, RuntimeError, ValueError):
41+
return None
42+
43+
3344
def _resolve_safe_root(raw_value: str, default_path: Path) -> Path:
34-
workspace_base = os.path.normpath(str(WORKSPACE_ROOT.resolve()))
35-
default_root = Path(default_path).resolve()
45+
default_root = _resolve_workspace_path(default_path)
46+
if default_root is None:
47+
return WORKSPACE_ROOT.resolve()
3648

3749
raw = str(raw_value or "").strip()
3850
if not raw:
3951
return default_root
4052

41-
if not os.path.isabs(raw):
42-
fullpath = os.path.normpath(os.path.join(workspace_base, raw))
43-
else:
44-
fullpath = os.path.normpath(raw)
45-
46-
if os.path.commonpath([workspace_base, fullpath]) != workspace_base:
47-
return default_root
48-
return Path(fullpath)
53+
resolved = _resolve_workspace_path(Path(raw))
54+
return resolved or default_root
4955

5056

5157
def _render_json(path: str, payload: dict[str, Any] | None) -> None:
@@ -58,21 +64,20 @@ def _render_json(path: str, payload: dict[str, Any] | None) -> None:
5864

5965
def _read_json_file(*, base_dir: Path, pack_id: str, filename: str) -> dict[str, Any] | None:
6066
try:
61-
workspace_base = os.path.normpath(str(WORKSPACE_ROOT.resolve()))
62-
base_path_obj = base_dir if base_dir.is_absolute() else (WORKSPACE_ROOT / base_dir)
63-
base_path = os.path.normpath(str(base_path_obj.resolve()))
64-
if os.path.commonpath([workspace_base, base_path]) != workspace_base:
67+
base_path = _resolve_workspace_path(base_dir)
68+
if base_path is None:
6569
return None
6670

6771
safe_pack_id = _normalize_pack_id(pack_id)
6872
if not safe_pack_id:
6973
return None
7074

71-
fullpath = os.path.normpath(os.path.join(base_path, safe_pack_id, filename))
72-
if os.path.commonpath([base_path, fullpath]) != base_path:
75+
resolved_path = (base_path / safe_pack_id / filename).resolve(strict=False)
76+
try:
77+
resolved_path.relative_to(base_path)
78+
except ValueError:
7379
return None
7480

75-
resolved_path = Path(fullpath)
7681
if not resolved_path.exists() or not resolved_path.is_file():
7782
return None
7883

0 commit comments

Comments
 (0)