Skip to content

Address non-scanner review findings#4

Merged
ko1N merged 9 commits into
mainfrom
review/non-scanner-findings
Jun 25, 2026
Merged

Address non-scanner review findings#4
ko1N merged 9 commits into
mainfrom
review/non-scanner-findings

Conversation

@killerra

@killerra killerra commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Addresses the non-scanner findings from the full code review. The scan-engine
items (scan.rs: VM-*, SCAN-*) are intentionally left for a separate,
focused PR.

Highlights

  • Correctness (FMT-5): pointer_size_bytes() was hardcoded to 8 and never
    overridden, so * (Ptr), Skip(0), and Push(0) read 8 bytes on 32-bit
    ELF/Mach images — both of which the wrappers accept (32-bit fixtures ship in the
    repo). Now derived from the image class (elf.is_64 / MachO.is_64); PE is
    unaffected (it already rejects non-64). Covered by a new fixture test.

What's included

  • Parser (PARSE-1..6): reject unbalanced {/} inside a group arm (was silently
    swallowed); drop a dead branch and the unused Parser source field; rewrite
    compile_alternatives iteratively (identical output); doc notes for trailing-skip
    stripping and Atom::Aligned's valid range.
  • Wrappers (FMT-1/2/3/4): factor ELF/Mach load mapping into a shared loadmap
    module; replace the Cell resolution caches with AtomicUsize so all three
    wrappers are Sync (parallel scanning) — asserted statically; doc the fat-Mach
    first-slice behavior and PE code-span extent convention.
  • Address (TYPE-2): mapped_c_str now requires the string to stay contiguous in
    mapped space (one extra terminator lookup, not one per byte) instead of scanning
    file bytes past a region boundary.
  • Macro (MACRO-2): pattern! misuse expands to compile_error! instead of
    panicking the compiler.
  • CI (CI-1): run workspace doctests (--all-targets skips them).
  • Benches (BENCH-1/2/3): first-match parity guard in pelite_compare; gate the
    shape dump behind SIGSCAN_BENCH_SHAPES; add a Mach scan group and a parse_perf
    bench.
  • CLI / profiling (CLI-1, FLAME-1/2/3): --quiet flag; [profile.release] debug = "line-tables-only" for readable flamegraphs; script/README perf notes.

Behavior changes (intentional, all more correct)

  • Patterns with an unbalanced brace inside a group arm now error instead of producing
    a malformed atom stream.
  • mapped_c_str returns None (instead of a possibly-wrong string) when a string
    would cross a mapping hole.
  • pattern! misuse is a compile error rather than a panic.

Deferred

All scan.rs engine items (VM-*, SCAN-*), FMT-6 (mapped-extent clamp — changes
scan coverage), and MACRO-1 (string → TokenStream rewrite).

Verification

cargo test --workspace --all-targets --all-features, cargo test --workspace --doc,
cargo clippy --workspace --all-targets --all-features -- -D warnings -D clippy::all,
and cargo fmt --all -- --check all pass.

killerra added 9 commits June 25, 2026 20:06
pointer_size_bytes() defaulted to 8 and was never overridden, so the
absolute-pointer (*) and pointer-width skip/push atoms read 8 bytes on
32-bit ELF/Mach-O images (both of which the wrappers accept). Override it
from the parsed image class (elf.is_64 / MachO.is_64). PE is unaffected
(it already rejects non-64). Adds a fixture test asserting the width.
- Enforce per-arm {/} balance in parse_group: an unbalanced brace inside an
  alternation arm (e.g. "(e8 ${ | 90)") was silently swallowed by the per-arm
  depth reset and produced a dangling Push/Jump with no Pop. Now rejected.
- Remove the unreachable empty-alternatives branch and the unused Parser
  source field (drops the struct lifetime).
- Rewrite compile_alternatives from recursion to an iterative right-fold
  (identical atom output, no per-arm recursion).
- Doc: note trailing-skip stripping and Atom::Aligned's valid range (<64).
- Add a private loadmap module (LoadMap/LoadRange) and use it from both the ELF
  and Mach wrappers, removing the duplicated LoadRange + lookup logic.
- Replace the Cell<Option<usize>> resolution caches in all three wrappers with
  a relaxed AtomicUsize, so PeFile/ElfFile/MachFile are Sync and a parsed image
  can be shared across threads for parallel scanning. Add a static Sync assertion.
- Document the fat-Mach first-slice behavior and the PE code-span extent convention.
mapped_c_str scanned for the terminating NUL in file space without checking
that the bytes stay contiguous in mapped space, so a string near a region's
end could read into unrelated, non-adjacent file bytes. Keep the fast file-space
NUL scan and verify contiguity with a single extra lookup of the terminator
(within a region the mapping is linear), mirroring mapped_slice_strict. Adds a
regression test.
Invalid pattern syntax, a non-string-literal argument, and bad escapes now
expand to a compile_error! at the call site instead of panicking the compiler,
giving a clear diagnostic. Valid patterns are unchanged.
cargo test --all-targets excludes doctests, leaving the crate's extensive
executable docs unvalidated. Add a dedicated --doc test step.
- pelite_compare: assert goblin/pelite first-match parity per case before
  timing, so a matching regression can't masquerade as a speedup (totals
  legitimately differ due to different code-scan scope).
- scan_perf: gate the per-pattern shape dump behind SIGSCAN_BENCH_SHAPES; add a
  Mach-O (aarch64) scan group.
- Add a parse_perf bench for the runtime pattern parser.
- CLI: --quiet/-q suppresses per-match output so the scan loop dominates a
  flamegraph instead of stdout formatting.
- workspace Cargo.toml: [profile.release] debug = "line-tables-only" for
  readable, inline-aware flamegraph frames.
- flamegraph-scan.sh / scripts README: use --quiet and note the Linux
  perf_event_paranoid requirement.
@killerra
killerra force-pushed the review/non-scanner-findings branch from b58bf1c to 96f3282 Compare June 25, 2026 19:41
@ko1N
ko1N merged commit 9c50620 into main Jun 25, 2026
3 checks passed
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