Skip to content

fix(scan): read the hunks and the encodings the scan claims to cover - #32

Merged
rmyndharis merged 1 commit into
mainfrom
fix/scan-coverage
Aug 12, 2026
Merged

fix(scan): read the hunks and the encodings the scan claims to cover#32
rmyndharis merged 1 commit into
mainfrom
fix/scan-coverage

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Two ways a commit-time scan reported full coverage of content it never read.

Forged diff headers

A unified diff renders an added line as + followed by its content. A source
line starting ++ therefore arrives as +++ ..., which is the same shape as a
new-file header. collectLineRanges read it as one: it reassigned the current
path to a file that does not exist, filed every later hunk of the real file
under that path, and returned line ranges nothing would query. The rest of the
file was never handed to the content rules, and the scan still reported
complete: true, so no incomplete reason was recorded and the fail-closed
carve-outs never engaged.

Hunk bodies now run against the line budget each @@ header declares — both
sides, since Git emits every - line before every + line — so a header is
only recognised where one can appear. A diff --git line resets the current
path; content cannot forge that prefix, which makes it the one reliable resync
point if a body ever ends short.

++ /dev/null is the same defect through a different branch: it set the current
path to null and dropped the remaining hunks rather than misfiling them. The
budget covers both.

UTF-16 text classified as binary

isBinary returns true on the first NUL byte, so UTF-16 text skipped whole and
the scan stayed complete. PowerShell 5.1 writes UTF-16LE from >, Out-File
and Tee-Object, so a Windows developer could commit a marker file no content
rule ever read.

A byte-order mark says the bytes are text, so a marked blob is now decoded and
scanned. Only the mark is trusted. Unmarked NUL data still skips as binary:
guessing there would decode images into garbage and feed it to the rules, and on
clean a spurious block unstages the user's asset. FF FE 00 00 opens UTF-32LE
and is left alone. An odd-length blob falls through to the binary skip rather
than crashing swap16, and the big-endian path byte-swaps a copy so the read
batch is not mutated.

The oversize probe is deliberately untouched. Decoding there would flip an
oversized UTF-16 file from a silent binary skip to a fatal size-limit, and
strict returns 31 unconditionally on that — a new hard refusal for any repo
holding a large PowerShell transcript, bought for no detection the in-budget
path does not already give.

Tests

Five added. Two cover a commit whose added line forges each header shape, with
the marker in a later hunk. Three cover UTF-16: little-endian and big-endian
marked text must scan, and an odd-length blob claiming a mark must not crash.
The existing binary-skip test keeps its assertions and gets an accurate comment:
it pins unmarked NUL data, not the PowerShell case.

Full suite green.

Two ways a commit-time scan reported full coverage of content it never read.

A unified diff renders an added line as `+` followed by its content, so source
starting `++ ` arrives as `+++ ...`, the same shape as a new-file header. The
hunk parser read it as one, filed every later hunk of that file under a path
nothing scans, and still reported the scan complete. Hunk bodies now run against
the line budget each `@@` header declares, so a header is only recognised where
one can appear. A `diff --git` line resets the current path, since content
cannot forge that prefix.

UTF-16 text was classified as binary on its NUL padding and skipped. A byte-order
mark says the bytes are text, so a marked blob is decoded and handed to the
content rules. PowerShell 5.1 writes exactly that from `>`, `Out-File` and
`Tee-Object`. Unmarked NUL data still skips as binary, and an odd-length blob
falls through instead of crashing the byte swap.
@rmyndharis rmyndharis changed the title Read the hunks and the encodings the scan claims to cover fix(scan): read the hunks and the encodings the scan claims to cover Aug 12, 2026
@rmyndharis
rmyndharis merged commit 21fa107 into main Aug 12, 2026
8 checks passed
@rmyndharis
rmyndharis deleted the fix/scan-coverage branch August 12, 2026 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant