Skip to main content

max / shop

3.0 KB · 63 lines History Blame Raw
1 # Seed corpora
2
3 Hand-written and real starting inputs, one directory per fuzz target. These are
4 committed; `corpus/` is not.
5
6 The split follows `astra-soak-overview`, which calls a minimized corpus
7 "accumulated compute, not a build artifact":
8
9 - **These seeds are human intent.** The `doc-` files are the protocol
10 documentation's own examples. The `real-` files are genuine transmissions: a
11 48x48 PNG off this machine sent both single-shot and in the 4096-character
12 chunks a client actually uses, and raw RGB and RGBA frames whose dimensions
13 agree with their payloads. Three are transmissions long enough to be chunked
14 in earnest: a 64x64 RGBA frame in twenty-two 1024-character chunks, two
15 chunked transmissions under different `i=` values sent back to back, and an
16 animation that transmits a root frame, appends to it, composes and deletes.
17 Chunk equivalence is the
18 property with teeth in this oracle, and a corpus whose every payload fits in
19 one body never reaches it. The rest is one file per shape worth reaching in
20 the first second rather than the first hour: each medium a query can ask
21 about, each way a chunked transfer is keyed, and the malformed bodies that
22 sit one mutation away from a valid one.
23 - **`corpus/` is machine output and lives on astra**, under the soak runner's
24 persistent directory. Minimize with `cargo +nightly fuzz cmin apc` and commit
25 it once it represents real soak hours, not before.
26
27 ## Input format
28
29 The input is split on ESC and each piece has a leading `_` and a trailing `\`
30 stripped, so a seed is what a client writes to the terminal, verbatim. A file
31 holding several APCs is one session through one parser, which is how chunked
32 transfers and the never-evicted partial state get reached at all.
33
34 Run against these on a machine with no corpus:
35
36 mkdir -p fuzz/corpus/apc
37 cargo +nightly fuzz run apc fuzz/corpus/apc fuzz/seeds/apc
38
39 The `mkdir` is needed once. `cargo fuzz` creates the default corpus directory
40 for you only when you name no directories at all; pass them explicitly and
41 libFuzzer requires every one to exist already.
42
43 **Name the corpus directory first and this one second.** libFuzzer writes new
44 inputs into whichever directory it is given first and treats the rest as
45 read-only. Passing `fuzz/seeds/apc` alone dumps thousands of machine-generated
46 files in here and buries the hand-written ones, which is exactly the split this
47 directory exists to keep.
48
49 ## Where real payloads come from
50
51 Not from `kitten icat`: headless it cannot open a controlling terminal, and
52 under `script(1)` it refuses because the terminal reports no pixel size. There
53 is no kitty graphics test corpus in the Debian package either. The two routes
54 that work are building the payloads from a real image, which is what the
55 `real-` seeds are, and recording a live client with `shop --record PATH`, which
56 tees the PTY byte stream through `Pty::set_recorder`.
57
58 ## Crash seeds
59
60 An input that once found a bug stays here forever, and also becomes a file
61 under `fuzz/regressions/`, which `tests/regressions.rs` replays on stable. None
62 yet.
63