Repository navigation
buildcheck: catch a patch hunk header that lies about its size - #495
bernardladenthin wants to merge 1 commit into
Conversation
The guard for the regression that put 23 jobs of one Publish run in the red, and the reason it got
through: `git apply --check` validates that a hunk's CONTEXT applies, not that its declared line
count matches its body. A header that under-counts therefore passes the check, and `git apply`
writes only the declared number of lines -- silently truncating the file. Editing a comment inside
the new file `patches/0017` adds left its header at `+1,25` for 27 lines, so prefetch.h arrived
without its closing brace, every translation unit including it continued inside an unclosed
function, and quants.c failed 19x with "function definition is not allowed here" on every platform.
Nothing existing could see it. The applier treats a truncated file as a successful apply, and
verify-patches-applied.sh asserts only that every patch is in the stamp and that the tree is dirty
-- both true. So this is a STATIC check of the patch files, wired into `code-style` (the first
minutes of a run) rather than after a build, and runnable before a push:
python3 .github/check-patches.py
The algorithm is the part worth reading, because two obvious forms of it are wrong and one of them
accepts exactly this bug. Counting body lines until the next delimiter over-counts trailing context
AND passes a header that under-counts. Only checking that a body is not SHORT misses it as well.
The correct form is: consume exactly as many lines as the header declares, then require that a
delimiter follows -- a body that ends early is short, a body that continues is under-counted, and
both messages say what `git apply` would do about it.
11 unit tests cover both directions, a wrong old-side count, the `@@ -5 +5 @@` single-line
shorthand, "\ No newline at end of file" counting for neither side, prose and a git signature below
the last hunk (this repository's patches carry long descriptions), and that every hunk of a
multi-hunk patch is checked. One of them runs the check over the repository's own 11 patches, which
pass. Full buildcheck suite: 114 tests green.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2h8gXyyE5UeimkL9vQv9G
|
Closing as a duplicate of #493, which is merged. The other session built the same guard independently and arrived at the same algorithm -- consume the declared count, then require a delimiter -- so it catches both directions, including the under-count that truncates the file. Its version is better in two respects: it tracks the Checked rather than assumed before closing: the four test cases this PR had and #493 does not (the |
The guard for the regression that put 23 jobs of one Publish run in the red — and for the reason
it got through in the first place.
Why nothing caught it
git apply --checkvalidates that a hunk's context applies, not that its declared line countmatches its body. A header that under-counts passes the check, and
git applythen writes onlythe declared number of lines — silently truncating the file.
Editing a comment inside the new file
patches/0017adds left its header at@@ -0,0 +1,25 @@for27 lines, so
prefetch.harrived without its closing brace, every translation unit including itcontinued inside an unclosed function, and
quants.cfailed 19 ×function definition is not allowed hereon every platform.Nothing existing could see it:
git apply --checkapply-llama-patches.cmakeverify-patches-applied.shThe check
Static, so it runs in
code-style(the first minutes of a run) rather than after a build, andlocally before a push:
The algorithm is the part worth reading, because two obvious forms are wrong and one of them
accepts exactly this bug. Counting body lines until the next delimiter over-counts trailing
context and passes a header that under-counts. Only checking that a body is not SHORT misses it
too. The correct form: consume exactly as many lines as the header declares, then require a
delimiter to follow — a body that ends early is short, a body that continues is under-counted.
Both messages say what
git applywould do about it, and the under-count one names the first linethat would be dropped.
Tests
11 unit tests: both directions, a wrong old-side count, the
@@ -5 +5 @@single-line shorthand,\ No newline at end of filecounting for neither side, prose and a git signature below the lasthunk (this repository's patches carry long descriptions above the diff), and that every hunk of a
multi-hunk patch is checked. One runs the check over the repository's own 11 patches.
Verified red/green on the real thing: reconstructing the broken header reports
which is precisely the line that went missing.
Full buildcheck suite: 114 tests green (103 + 11).
Not shared
patches.pyis jllama-only — only this repository hasllama/patches/— so it is deliberately notin
.github/shared-files.sha256and not in__init__.py's shared list.🤖 Generated with Claude Code
https://claude.ai/code/session_01E2h8gXyyE5UeimkL9vQv9G