Skip to content

test(analyses): scan the whole file for the bot-filter collapse - #274

Merged
emrecdr merged 1 commit into
mainfrom
fix/bot-filter-whole-file-scan
Aug 14, 2026
Merged

test(analyses): scan the whole file for the bot-filter collapse#274
emrecdr merged 1 commit into
mainfrom
fix/bot-filter-whole-file-scan

Conversation

@emrecdr

@emrecdr emrecdr commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Validating the cycle-13 audit confirmed its new finding, and fixing it reproduced the same defect one level down.

F307 — the matcher read one line at a time

F305 taught this guard that SQL is case-insensitive and whitespace-tolerant, then normalised each line independently. A call wrapped across lines is never assembled, so its argument is never seen.

Confirmed by planting BOOL_OR( with a.is_bot on the next line inside a SQL string literal — the guard passed.

Not a hypothetical layout. analyses/ownership.rs already writes SUM( with its argument and closing paren on their own lines, in the very directory this scans. A BOOL_OR( whose argument grew that long would be written the same way by the same convention.

Fix: normalise the file once, map matches back to a file line by counting newlines in the prefix — the technique spa_escaping_test already uses.

The bug inside the fix, recorded because it is the same class

My first mapping indexed its offset table per character while match_indices returns byte offsets. On any file containing a multi-byte char — and these contain them in their prose — the table drifts. The guard detected the right thing and named the wrong line:

before:  soc.rs:142: _bot
after:   soc.rs:141: BOOL_OR(

Caught only because the regression test read the reported location, not just pass/fail. A guard that names the wrong line is one people stop trusting.

Verification

case result
wrapped SQL, qualified column previously passed → now fails, naming the construct's line
all four single-line spellings still caught
clean tree still clean

Also: the Trusted Publishing deferral's reason was wrong

I deferred it claiming cargo publish executes build.rs and so cannot hold id-token under SLSA L3. Only the verification step builds, and --no-verify switches it off. Reproduced independently on cargo 1.97.1 (the audit used 1.95.0), with a control:

command build.rs executed
cargo package --no-verify no
cargo package yes

The architecture is compatible. The deferral stands on sequencing instead: Trusted Publishing must be configured per-crate on crates.io — outside this repository — and switching the workflow before that exists breaks the next release. Recorded so the next cycle doesn't re-derive a resolved argument.

clippy and fmt verified by exit status.

F305 taught this guard that SQL is case-insensitive and whitespace-
tolerant, then normalised each line on its own. A call wrapped across lines
is never assembled, so its argument is never seen — confirmed by planting
`BOOL_OR(` with `a.is_bot` on the next line, which the guard passed.

Not a hypothetical layout. `analyses/ownership.rs` already writes `SUM(`
with its argument and closing paren on their own lines, in the very
directory this scans. A `BOOL_OR(` whose argument grew that long would be
written the same way by the same convention.

The file is normalised once and matches map back to a file line by counting
newlines in the prefix — the technique `spa_escaping_test` already uses to
report a file line from a statement offset.

The first implementation of that mapping had the same defect one level
down: it indexed its offset table per character while `match_indices`
returns byte offsets, so the table drifted on any file containing a
multi-byte char, and these contain them in their prose. It detected the
right thing and named the wrong line. Fixed by sizing the table in bytes.
Caught only because the regression test read the reported location rather
than the pass/fail — a guard that names the wrong line is one people stop
trusting.

Also records that the Trusted Publishing deferral's stated reason was
wrong. Only `cargo publish`'s verification step builds, and `--no-verify`
switches it off — reproduced here on cargo 1.97.1 with a control. The
architecture is compatible; the real blockers are that trusted publishing
must be configured per-crate on crates.io, outside this repository, and
that switching before it exists breaks the next release. Sequencing, not
incompatibility.
@emrecdr
emrecdr merged commit 368f7d2 into main Aug 14, 2026
14 checks passed
@emrecdr
emrecdr deleted the fix/bot-filter-whole-file-scan branch August 14, 2026 07:59
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.

2 participants