Skip to content

Commit 0682f91

Browse files
committed
restore changes
1 parent e938b5e commit 0682f91

2 files changed

Lines changed: 8 additions & 37 deletions

File tree

app/scenario_planning.py

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,8 @@ def _normalize_pack_id(value: Any) -> str:
3333
def _resolve_workspace_path(candidate: Path) -> Path | None:
3434
try:
3535
workspace_root = WORKSPACE_ROOT.resolve()
36-
base_str = os.path.abspath(str(workspace_root))
37-
if not base_str.endswith(os.sep):
38-
base_str += os.sep
39-
40-
raw_str = str(candidate)
41-
if os.path.isabs(raw_str):
42-
target_str = os.path.abspath(raw_str)
43-
else:
44-
target_str = os.path.abspath(os.path.join(base_str, raw_str))
45-
46-
if not target_str.startswith(base_str) and target_str != base_str.rstrip(os.sep):
47-
return None
48-
49-
# Fully contained lexically, now safe to resolve symlinks
50-
resolved = Path(target_str).resolve(strict=False)
36+
raw_path = candidate if candidate.is_absolute() else (workspace_root / candidate)
37+
resolved = raw_path.resolve(strict=False)
5138
resolved.relative_to(workspace_root)
5239
return resolved
5340
except (OSError, RuntimeError, ValueError):
@@ -85,8 +72,10 @@ def _read_json_file(*, base_dir: Path, pack_id: str, filename: str) -> dict[str,
8572
if not safe_pack_id:
8673
return None
8774

88-
resolved_path = _resolve_workspace_path(base_path / safe_pack_id / filename)
89-
if resolved_path is None:
75+
resolved_path = (base_path / safe_pack_id / filename).resolve(strict=False)
76+
try:
77+
resolved_path.relative_to(base_path)
78+
except ValueError:
9079
return None
9180

9281
if not resolved_path.exists() or not resolved_path.is_file():
@@ -614,7 +603,7 @@ def _render_flow_fallback(payloads: dict[str, Any]) -> None:
614603
data_root=data_root,
615604
output_root=output_root,
616605
output_pack_id=_normalize_pack_id(output_pack_override.strip()) or None,
617-
) or {}
606+
)
618607
paths = dict(bundle.get("paths") or {})
619608
payloads = dict(bundle.get("payloads") or {})
620609
slot_labels = _load_scenario_slot_labels()

src/omen/scenario/loader.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import json
6-
import os
76
from pathlib import Path
87
from typing import Any
98

@@ -18,17 +17,6 @@ def _read_json(path: Path) -> dict[str, Any] | None:
1817
return payload if isinstance(payload, dict) else None
1918

2019

21-
def _is_safe_subpath(base: Path, subpath: str) -> bool:
22-
"""Validate that the given subpath resolves strictly within the base directory."""
23-
if not subpath:
24-
return False
25-
base_str = os.path.abspath(str(base))
26-
if not base_str.endswith(os.sep):
27-
base_str += os.sep
28-
target_str = os.path.abspath(os.path.join(base_str, str(subpath)))
29-
return target_str.startswith(base_str)
30-
31-
3220
def discover_spec8_pack_candidates(
3321
data_root: str | Path = "data/scenarios",
3422
output_root: str | Path = "output",
@@ -68,13 +56,9 @@ def load_spec8_flow_artifacts(
6856
data_root: str | Path = "data/scenarios",
6957
output_root: str | Path = "output",
7058
output_pack_id: str | None = None,
71-
) -> dict[str, Any] | None:
59+
) -> dict[str, Any]:
7260
data_base = Path(data_root)
7361
output_base = Path(output_root)
74-
75-
if not _is_safe_subpath(data_base, pack_id):
76-
return None
77-
7862
data_pack = data_base / pack_id
7963

8064
situation = _read_json(data_pack / "situation.json")
@@ -85,8 +69,6 @@ def load_spec8_flow_artifacts(
8569
generation_trace = _read_json(data_pack / "generation" / "log.json")
8670

8771
resolved_output_pack = output_pack_id or pack_id
88-
if not _is_safe_subpath(output_base, resolved_output_pack):
89-
return None
9072
result = _read_json(output_base / resolved_output_pack / "result.json")
9173
explanation = _read_json(output_base / resolved_output_pack / "explanation.json")
9274

0 commit comments

Comments
 (0)