Skip to content

Harden inline-container safety and reduce query/text allocations - #2

Merged
egorsmkv merged 1 commit into
masterfrom
improve/rust-audit
Oct 8, 2026
Merged

egorsmkv merged 1 commit into
masterfrom
improve/rust-audit

Conversation

@egorsmkv

@egorsmkv egorsmkv commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Inline storage exposed a safe raw-mutation method that could invalidate initialized values, and map spill could double-drop moved storage if Hash/Eq panicked. Make raw mutation explicitly unsafe, track the initialized prefix before moving entries, and clean up partial Clone results on unwind. Fix Bytes ordering to agree with content-based equality and make inline map replacement consistent with heap behavior; retain the first ordinary HTML attribute.

Remove per-anchor Context clones in :has by passing a borrowed scope boundary. Flatten decoded-text extraction into one output buffer and borrow unchanged single leaves. Add regression tests, Criterion/probe workloads, path-filtered CI for default/std/entities, Rust 1.92 and pinned nightly SIMD, plus optional manual Miri. Update API/installation/safety/performance documentation.

Validation: 89 unit tests with entities, 86 with std, 3 bounded default tests plus doctests; strict all-targets Clippy in default/entities without allowances; rustdoc with -D warnings; Rust 1.92 all-target compatibility; nightly SIMD tests; benchmark smoke checks, formatting, YAML and relative links. Focused Miri groups passed 7 + 7 + 22 test executions (some overlap). Baseline tests independently reproduce incorrect Bytes ordering, both clone leaks and duplicate map replacement. Pedantic review was inspected; unrelated style warnings remain.

Measured 200-row warm-DOM operations on the same shared x86_64 host/compiler/lockfile, Criterion 0.3.6, 100 samples, 3 s warmup/5 s measurement, two runs per revision:

  • li:has(a): 271–277 µs → 118–122 µs; allocations 606 → 6, requested bytes 4,832,160 → 24,160.
  • Decoded aggregate text: 11.46–11.50 µs → 5.95–5.98 µs; allocations 401 → 1, with 8 reallocations in both revisions.
  • An unchanged single leaf measured 0 allocation/reallocation calls, excluding DOM/query setup.

These are exploratory operation-specific results, not general parser/crawler speed guarantees. Repeated raw parsing comparisons were small/mixed (Example Domain changed sign, PyPI no significant change then about -2.7%); no general parsing speedup is claimed. See docs/rust-audit.md for confidence intervals, measurement boundaries, scope and reproduction commands.

Compatibility: inline_parts_mut now requires unsafe, intentionally closing a safe-API soundness hole. Publish with the already-planned breaking 0.3.x release; no version bump, tag or publication is performed here. Full HTML5 recovery and silkworm's scraper::Selector migration remain outside this change. Remote CI results are separate from local validation.

@egorsmkv
egorsmkv merged commit 7e5ba12 into master Oct 8, 2026
4 checks passed
@egorsmkv
egorsmkv deleted the improve/rust-audit branch October 8, 2026 15:16
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