diff --git a/src/alscan/parser.py b/src/alscan/parser.py index 01a4300..3402b8f 100644 --- a/src/alscan/parser.py +++ b/src/alscan/parser.py @@ -35,6 +35,11 @@ def parse_als(path: str | Path) -> Project: path = Path(path).resolve() if not path.exists(): raise FileNotFoundError(str(path)) + file_size = path.stat().st_size + if file_size == 0: + raise ValueError(f"ALS file is empty: {path}") + if file_size < 50: + raise ValueError(f"ALS file is too small to be valid ({file_size} bytes): {path}") raw = path.read_bytes() if raw[:2] == b"\x1f\x8b": buf = io.BytesIO(raw) diff --git a/src/alscan/services.py b/src/alscan/services.py index f1bf76c..d0c2876 100644 --- a/src/alscan/services.py +++ b/src/alscan/services.py @@ -316,6 +316,11 @@ def save_report( dest: Path, source_paths: list[Path] | None = None, ) -> Path: + """Save a report to dest with safety validation. + + validate_output_dest() includes validate_parent() which checks for + symlink/junction traversal in path components. + """ sources = source_paths or [] try: validate_output_dest(dest, sources)