cargo-fuzz scaffold for fuzz-tests. This is a detached workspace
(fuzz/Cargo.toml has its own [workspace] table) so it never gets pulled
into the main cargo build --workspace / cargo test --workspace run —
fuzzing needs nightly and its own dependency resolution.
fuzz_targets/utf8_input.rs— feeds arbitrary bytes intofuzz_tests::utf8_input, asserting it never panics regardless of input.fuzz_targets/parse_u32_lenient.rs— feeds arbitrary (valid-UTF-8) strings intofuzz_tests::parse_u32_lenient, asserting it never panics.
cargo install cargo-fuzz # once per machine
cd fuzz
cargo +nightly fuzz build
cargo +nightly fuzz run utf8_input
cargo +nightly fuzz run parse_u32_lenientCorpus and crash artifacts land in fuzz/corpus/ and fuzz/artifacts/,
both gitignored — libFuzzer grows corpus/ unboundedly as it discovers new
inputs, which isn't something to commit.
fuzz/seed_corpus/<target>/ holds a handful of small, curated starting
inputs per target (committed, unlike the auto-grown corpus/) — valid and
invalid cases picked by hand rather than discovered by the fuzzer. Feed
them in explicitly:
cargo +nightly fuzz run utf8_input fuzz/seed_corpus/utf8_input
cargo +nightly fuzz run parse_u32_lenient fuzz/seed_corpus/parse_u32_lenient(cargo fuzz run <target> [extra_corpus_dirs...] reads any positional
directories beyond the default corpus/<target>/ as additional seed
input — it doesn't replace the default corpus dir.)
- Add a
[[bin]]entry tofuzz/Cargo.toml. - Add the matching
fuzz_targets/<name>.rsusing thefuzz_target!macro fromlibfuzzer-sys, exercising a function fromfuzz-tests(or whichever crate you're fuzzing). - CI builds every target on nightly via the
fuzz-buildjob in.github/workflows/ci.yml; no separate wiring needed.