Skip to content

Harden glob compilation + property/fuzz tests; edition 2024, MSRV 1.85, release 0.2.0 - #1

Merged
prostomarkeloff merged 2 commits into
mainfrom
harden-glob-and-bump-0.2.0
Jun 3, 2026
Merged

Harden glob compilation + property/fuzz tests; edition 2024, MSRV 1.85, release 0.2.0#1
prostomarkeloff merged 2 commits into
mainfrom
harden-glob-and-bump-0.2.0

Conversation

@prostomarkeloff

Copy link
Copy Markdown
Owner

Harden glob compilation + property/fuzz tests; edition 2024, MSRV 1.85, release 0.2.0

TL;DR

Closes a compile-time DoS in the glob engine (a short brace "bomb" could OOM Pattern::compile), backs the engine's safety claims with proptest + cargo-fuzz, modernizes the toolchain to edition 2024 / MSRV 1.85, and cuts v0.2.0.

Why

The README promised "linear-time, no catastrophic backtracking on untrusted patterns" — but that only covered matching. Brace compilation was the gap: {a,b}{c,d}… is a cross product, so a short adversarial pattern ({a,b} ×30 — a few bytes) demanded 2³⁰ sub-patterns and blew up memory at compile time, before the linear matcher ever ran. directiva::source::file parses untrusted directive files, so this was reachable.

Separately, the declared rust-version = "1.74" was fiction: pyo3 0.28 (the python feature) already needs 1.83, and nothing verified the floor.

What changed

The fix — bounded compilation. Brace expansion now caps the running cross product at a public MAX_BRACE_ALTS (core::glob, = 1024). A pattern that would exceed it degrades to a single literal alternative (braces matched verbatim — the same leniency already applied to an unmatched brace). The check happens before allocation, so both time and memory stay O(cap · depth) on any input — never O(2ⁿ).

Property tests (proptest, a dev-dependency). Run as part of cargo test:

  • parser is total (returns Result, never panics) and any Ok has a non-empty action + NAME;
  • glob compile is total and bounded (alt_count ∈ [1, MAX_BRACE_ALTS]), matches never panics, metachar-free patterns are full-anchored.

Fuzzing (cargo-fuzz). A standalone fuzz/ crate (own workspace, nightly-only) with parse and glob targets; the glob target asserts the brace cap as a fuzz invariant. Excluded from the published crate. Both targets ran clean locally (~478k / ~611k execs, 0 crashes, ASan).

Toolchain. Edition 2021 → 2024; MSRV 1.74 → 1.85 (edition floor, ≥ pyo3's 1.83), now pinned by a dedicated CI job (cargo test + cargo check --features python on 1.85).

Release. Version 0.1.0 → 0.2.0 + README install references.

Testing

  • cargo test64 tests pass (was 56: +brace-cap units, +5 proptest properties).
  • cargo clippy --all-targets -- -D warnings and cargo clippy --features python -- -D warnings — clean.
  • cargo fmt --check — clean.
  • Verified on a real 1.85.0 toolchain: default cargo test green, cargo check --features python green.
  • cargo +nightly fuzz run parse|glob — clean.

Notes

  • nightly is required only to run the fuzzers (cargo-fuzz needs -Zsanitizer*); the library, tests, proptest, and clippy are all stable.
  • No public API removed; MAX_BRACE_ALTS is the one new public item.

…RV 1.85

- Cap brace expansion at MAX_BRACE_ALTS so a short "{a,b}"×N brace bomb can
  no longer OOM Pattern::compile; a pattern past the cap degrades to a single
  literal alternative (same leniency as an unmatched brace).
- Add proptest properties for the parser (totality, non-empty action/name on
  Ok) and the glob engine (compile is total and bounded, literals are
  full-anchored, brace strings stay within the cap).
- Add a standalone cargo-fuzz crate with parse + glob targets; the glob target
  asserts the brace cap as a fuzz invariant. Exclude /fuzz from the published
  crate.
- Bump to edition 2024 and raise MSRV to 1.85 (edition floor, also >= pyo3 0.28
  which needs 1.83); add a CI job that builds + tests on 1.85.
Bump the crate version 0.1.0 -> 0.2.0 and the README install references.
@prostomarkeloff
prostomarkeloff merged commit fd17434 into main Jun 3, 2026
8 checks passed
@prostomarkeloff
prostomarkeloff deleted the harden-glob-and-bump-0.2.0 branch June 3, 2026 19:08
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