test(fuzz): add dedicated parse_idlist fuzz targets and make the README claim true - #4
Draft
h4x0r wants to merge 3 commits into
Draft
test(fuzz): add dedicated parse_idlist fuzz targets and make the README claim true#4h4x0r wants to merge 3 commits into
h4x0r wants to merge 3 commits into
Conversation
The README, docs/index.md and the CHANGELOG all advertised "fuzzed", but
fuzz/fuzz_targets/ was empty and no target existed anywhere in history —
ADR 0003 recorded this honestly as a known gap. ADR-0012 requires a fuzz
target per parsed structure for any crate that parses untrusted input, and
shell-item blobs are lifted verbatim from .lnk LinkTargetIDList structures
and registry ShellBags values.
Two targets, following the fleet pattern (lnk-forensic, shellhist-forensic
for the naming and CI job; xpress-huffman, safe-read for the single-crate
fuzz manifest with path = ".."):
idlist parse_idlist alone — the cb framing loop, the class dispatch,
the per-class decoders and the 0xbeef0004 extension block.
pipeline parse_idlist to reconstruct_path to display_name — the joins
and label selection over lossily-decoded UTF-16, where a
char-boundary assumption would surface rather than in parse.
lnk-forensic and winreg-forensic already fuzz harnesses that reach this
code incidentally through their own readers; that is not a substitute for
a dedicated target and does not make a first-person claim true.
Both run clean on first use, with no crashes found:
idlist 8,229,495 executions in 121s
pipeline 9,131,724 executions in 121s
(local, aarch64-apple-darwin, libFuzzer, -max_total_time=120). No crashes
in N executions is present-robustness evidence over the inputs libFuzzer
reached; it does not prove that no panicking input exists. The static
lints remain the load-bearing guarantee.
CI gains a nightly smoke-fuzz job matching the sibling repos, building all
targets with `cargo fuzz check` then running each for 30s on every PR.
cargo-fuzz is installed via the same pinned taiki-e/install-action already
used for cargo-llvm-cov rather than an unpinned `cargo install`.
CONTRIBUTING named `shelllink` and `forensic` — lnk-forensic's target
names, carried over when this repo's scaffolding was copied from it, and
wrong here even once targets existed. Corrected to idlist and pipeline.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The published README asserted the crate was "fuzzed over `parse_idlist`" while no fuzz target existed. The preceding commit made a dedicated target real; this makes the documentation say what is actually true and measured rather than merely asserted. README "Trust but verify" moves to the fleet's canonical paired-bullet form: a Fuzzed bullet carrying the empirical evidence (both target names, what each drives, and the exec counts reached) beside a Panic-free-by-lint bullet carrying the static posture. Per the fleet's evidence-based-rigor rule these are complementary, not interchangeable — the lints make panics unreachable by construction, the fuzzer tests that empirically over a finite number of inputs. Also corrected in the same sentence: the README cited `#![forbid(unsafe_code)]` as an inner attribute, but the lint is declared in Cargo.toml `[lints.rust]` as `unsafe_code = "forbid"`. Same guarantee, but a reader grepping for the attribute would not have found it. ADR 0003's "Known gap" consequence and docs/PRD.md's validation section both said no fuzz target was committed and no ci.yml existed. The fuzz half is closed by the preceding commit; the ci.yml half was already stale, since ci.yml runs clippy -D warnings, the low-MSRV job and the coverage gate today. Both now describe the current state, and both keep the limit of the evidence explicit rather than reading the exec counts as proof of absence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
…ot musl
The fuzz job failed on the first CI run:
error: sanitizer is incompatible with statically linked libc,
disable it using `-C target-feature=-crt-static`
error[E0463]: can't find crate for `std`
note: the `x86_64-unknown-linux-musl` target may not be installed
I had installed cargo-fuzz via the pinned taiki-e/install-action already used
in this workflow for cargo-llvm-cov, preferring local consistency. That is the
cause: the prebuilt Linux cargo-fuzz binary is musl-linked, and cargo-fuzz
defaults --target to its own build triple, so it tried to build the targets for
x86_64-unknown-linux-musl. libFuzzer's sanitizers cannot link against a static
libc, and the musl std was not installed either.
`cargo install cargo-fuzz` compiles on the runner and therefore picks up the
gnu host triple. That is what lnk-forensic and shellhist-forensic do, and their
"Fuzz targets (nightly smoke)" jobs are green — matching the fleet was the right
call here and deviating from it was mine.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
README.mdclaimed the crate was "fuzzed overparse_idlist". It was not —fuzz/fuzz_targets/was empty andgit log --all -- fuzzreturned nothing, so no target ever existed.docs/decisions/0003-panic-free-forbid-unsafe-parsing.mdrecorded this honestly as a known gap.This PR closes the gap rather than softening the claim, then updates the docs to say what is measured.
What changed
New
fuzz/harness — two targets:idlistparse_idlistalone — thecbframing loop, class dispatch, per-class decoders,0xbeef0004extension blockpipelineparse_idlist→reconstruct_path→display_name— the joins and label selection over lossily-decoded UTF-16Patterned from
lnk-forensicandshellhist-forensic(target naming, CI job shape) andxpress-huffman/safe-read(single-crate fuzz manifest withpath = "..", standalone[workspace]).CI gains a nightly smoke-fuzz job matching the sibling repos —
cargo fuzz checkto build all targets, then 30s per target on every PR.cargo-fuzzinstalls via the same pinnedtaiki-e/install-actionalready used here forcargo-llvm-cov, rather than an unpinnedcargo install.Docs —
README.md,docs/index.md,docs/PRD.mdand ADR 0003 now describe the harness that exists.Measured results
Both targets ran clean on first use. No crashes found.
Local,
aarch64-apple-darwin, libFuzzer,-max_total_time=120 -rss_limit_mb=4096.This is present-robustness evidence over the inputs libFuzzer reached in that budget. It does not prove that no panicking input exists, and the docs say so — the static lints (
unsafe_code = "forbid",unwrap_used/expect_useddenied) remain the load-bearing guarantee, with the fuzzer as the empirical partner.On incidental coverage
lnk-forensicandwinreg-forensicboth depend onshellitemand have real fuzz harnesses that reach this code through their own readers. That does not make a first-person "fuzzed overparse_idlist" true — the claim asserts a dedicated harness, so one was added.Two smaller corrections found along the way
CONTRIBUTING.mdinstructed contributors to runcargo +nightly fuzz run shelllink # or: forensic—lnk-forensic's target names, carried over when this repo's scaffolding was copied from it. Wrong here even once targets existed.#![forbid(unsafe_code)]as an inner attribute; the lint is declared inCargo.toml[lints.rust]asunsafe_code = "forbid". Same guarantee, but a reader grepping for the attribute would not have found it.ADR 0003 and
docs/PRD.mdalso both stated "there is noci.ymlyet" — already stale, sinceci.ymlruns clippy-D warnings, the low-MSRV job and the coverage gate today. Corrected in the same pass.Gate
cargo build·cargo test(31 passed) ·cargo clippy --all-targets --all-features -- -D warnings·cargo fmt --all --check·cargo +nightly fmt --checkinfuzz/— all green.🤖 Generated with Claude Code