jay 3725ba1bfb
fix(skillscan): gate the directory scan file size before reading (#6359)
* fix(skillscan): gate the directory scan file size before reading

scan_skill_dir() read every candidate file with read_bytes() before any
size check; MAX_FILE_BYTES was only recorded as a finding afterwards.
Measured: one 300MB file (4.7x the 64MB limit) drives a 600MB peak
allocation and a 20s scan, linearly extrapolating to an OOM for larger
planted files - reachable via review/analyzer.py on content that never
passed the archive preflight gates.

Gate with stat() first and bound oversized reads to MAX_FILE_BYTES + 1,
mirroring _read_archive_member so both entry points share the same
discipline. Regression test plants an oversized file and fails if
read_bytes is used on it.

Closes #6358

* fix(skillscan): collapse to a single bounded read per file

Per review: Path.open + read(MAX_FILE_BYTES + 1) returns the whole file
when it is smaller than the limit, identical to read_bytes for regular
files - removing the size-conditional branch and closing the stat-to-read
race where a file growing past the limit between calls would still be
read unbounded. file_size from stat stays the source of truth for the
package-oversized-file evidence.
2026-10-06 17:55:51 +08:00
..