Bound the third hostile CSV, and stop two docs overclaiming

`forced_sub` was the last unbounded attacker-controlled list in
paramount.rs. `MAX_COM_INDICES` capped the two `*_com1_idx` attributes;
this one had nothing capping it at all, and unlike them it has no value
to filter — a cell is a classification of the position it sits at, so
its bound has to be positional. Extracted as `forced_subs` for the same
reason `com_indices` was extracted: through `labels_from_feature` the
bound is unobservable, because the subtitle loop cannot reach those
cells either, so the assertion could not fail.

The `MAX_COM_INDICES` doc claimed the entry-allocation argument for the
whole constant. It is the VALUE filter that caps the set (values below
the bound, so at most that many distinct entries, however long the
attribute); the `take` caps the WORK. Both are real and they are not
the same bound; the doc now says which is which.

`jar_inventory_dedup_is_not_quadratic` called itself proof by deadline.
It is a hang guard — a return to the linear scan runs for minutes and
would wedge CI rather than fail it — and no assertion in it can tell a
BTreeSet from any other sub-quadratic dedup. Renamed and documented for
what it does. Its margin was measured before keeping it: 0.14s debug /
0.07s release against 10s, ~70x, unlike the 6x that made paramount.rs's
wall-clock test flake.
This commit is contained in:
Matthew Jackson
2026-08-11 16:59:33 -07:00
parent 2d1563c63a
commit 8f9bde9b9a
2 changed files with 94 additions and 18 deletions
+13 -4
View File
@@ -1418,11 +1418,20 @@ mod registry_tests {
/// straight from the disc's UDF directory records, with attacker-chosen
/// name lengths to inflate each comparison.
///
/// Proof is by deadline. With the linear scan this fixture measures well
/// past the deadline; with a set it is milliseconds. Bounded so a
/// regression fails fast instead of hanging CI.
/// This is a HANG GUARD, and the name says so: a return to the linear scan
/// makes this fixture run for minutes (120 000² / 2 comparisons over a
/// 180-byte shared prefix), which without the deadline would wedge CI
/// rather than fail it. It is not a complexity proof — no assertion here
/// can distinguish `BTreeSet` from any other sub-quadratic dedup, and the
/// clock-free half of the claim (dedup, sort, directory exclusion) belongs
/// to `jar_inventory_dedups_sorts_and_skips_dirs` below.
///
/// The deadline is a real margin, unlike the 6x one that made
/// `paramount.rs`'s wall-clock test flake under a loaded CI box: measured
/// at 0.14 s debug / 0.07 s release against 10 s, so ~70x. A shared CPU
/// does not close that; a quadratic dedup does not survive it.
#[test]
fn jar_inventory_dedup_is_not_quadratic() {
fn jar_inventory_dedup_does_not_hang_on_a_hostile_directory() {
const FILES: usize = 120_000;
let (tx, rx) = std::sync::mpsc::channel();
let worker = std::thread::spawn(move || {