std/fuzz
std/fuzz
Section titled “std/fuzz”std/fuzz — byte-stream fuzzing harness layered on std/test. A fuzz target is a function that takes a string of bytes (the fuzz input) and returns Option[string] — same shape as a regular test: None — the input passed all the property checks Some(msg) — a counter-example: msg describes the violation, the runner records both the message + the offending input (escaped) so the failure log doubles as a reproducer. Inputs are drawn from a seed corpus the caller supplies, plus mutated variants of each seed (byte flip / byte insert / byte delete). Iteration count is fixed per call (iterations arg) — lang has no panic-recovery yet, so a fuzz target that genuinely crashes (out-of-bounds index, division by zero) aborts the whole run; that’s the trade for not needing a coroutine / fiber primitive. Real fuzzing frameworks add coverage feedback (libFuzzer / AFL) — we don’t, but the API is shaped so coverage can layer in later without a breaking change. Usage: function check_no_panic(input: string): Option[string] { // try to parse input; return Some if a property // we care about doesn’t hold. return None; } function main(): i32 { var r: TestRunner = test_new(“parser fuzz”); r = r.fuzz(“parse”, [“function main(): i32 { return 0; }”, ""], 100, check_no_panic); return r.finish(); } r.fuzz(name, seeds, iterations, target) reports as one TAP case (“ok N -
fuzz_default_iterations
Section titled “fuzz_default_iterations”pub function fuzz_default_iterations(): i32fuzz_default_iterations — used by callers that want the default loop count without pulling in a config constant per call site. Tuned to land sub-second runs on the small targets the migration uses; bigger property tests can pass a larger explicit count.
fuzz_run
Section titled “fuzz_run”pub function fuzz_run(seeds: string[], iterations: i32, target: (string) => Option[string]): Option[string]fuzz_run(name, seeds, iterations, target) — run the
target function against iterations inputs drawn from
seeds + mutations. Returns:
None — every input passed
Some(diagnostic) — the first failing input, with the
target’s message and the escaped
offending input embedded
Use through r.fuzz(...) rather than calling directly;
the receiver-method form folds the result into the
runner’s TAP stream.
pub function (r: test.TestRunner) fuzz(name: string, seeds: string[], iterations: i32, target: (string) => Option[string]): test.TestRunner(r) fuzz(name, seeds, iterations, target) — run a fuzz
target and report its outcome as a single TAP case.
Pass at most one fuzz target per it-equivalent line so
the failure attribution stays clean.
fuzz_run_shrink
Section titled “fuzz_run_shrink”pub function fuzz_run_shrink(seeds: string[], iterations: i32, target: (string) => Option[string]): Option[string]fuzz_run_shrink — run the regular fuzz loop, and on the first failure shrink the offending input to a minimal reproducer before returning. The diagnostic embeds both the original failing input AND the minimised one when they differ, so the log shows what the harness found AND what survived shrinking.
Counts shrink-time target(...) calls under a separate
budget that does NOT inflate the user-visible iterations
param — iterations is the mutation count, shrinking is
a post-process amortised against the first failure.
fuzz_shrink
Section titled “fuzz_shrink”pub function (r: test.TestRunner) fuzz_shrink(name: string, seeds: string[], iterations: i32, target: (string) => Option[string]): test.TestRunner(r) fuzz_shrink — receiver-method form. Reports as one TAP case; on failure the case message embeds the minimised counter-example so CI logs preserve a clean reproducer.
fuzz_corpus_from_dir
Section titled “fuzz_corpus_from_dir”pub function fuzz_corpus_from_dir(path: string): Result[string[], IoError]fuzz_corpus_from_dir(path) — load every regular file under
path as a seed string. Returns the seeds via Result so
the caller can fall back to inline seeds when the corpus
directory isn’t present (typical pattern: ship a small
inline corpus + grow it on disk over time).
fuzz_corpus_from_dir_or
Section titled “fuzz_corpus_from_dir_or”pub function fuzz_corpus_from_dir_or(path: string, fallback: string[]): string[]fuzz_corpus_from_dir_or(path, fallback) — convenience for the typical “use the on-disk corpus when present, else fall back to inline seeds” pattern:
var seeds: string[] = fuzz_corpus_from_dir_or( “testdata/parser_corpus”, ["", “function main(): i32 { return 0; }”]);
Concatenates the on-disk seeds AFTER the fallback so the inline ones are guaranteed to run even if the disk corpus is empty.