{"id":17137177,"url":"https://github.com/squeek502/zig-std-lib-fuzzing","last_synced_at":"2025-04-13T09:33:07.217Z","repository":{"id":65895546,"uuid":"408636773","full_name":"squeek502/zig-std-lib-fuzzing","owner":"squeek502","description":"A set of fuzzers for fuzzing various parts of the Zig standard library","archived":false,"fork":false,"pushed_at":"2024-04-24T21:14:53.000Z","size":440,"stargazers_count":41,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-05-02T01:59:37.451Z","etag":null,"topics":["fuzz-testing","fuzzing","zig"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/squeek502.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-21T00:03:26.000Z","updated_at":"2024-08-01T07:11:21.079Z","dependencies_parsed_at":"2024-08-01T07:11:20.483Z","dependency_job_id":"3109fd5c-cf2a-46fb-8efd-b3098f4885c7","html_url":"https://github.com/squeek502/zig-std-lib-fuzzing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squeek502%2Fzig-std-lib-fuzzing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squeek502%2Fzig-std-lib-fuzzing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squeek502%2Fzig-std-lib-fuzzing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squeek502%2Fzig-std-lib-fuzzing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squeek502","download_url":"https://codeload.github.com/squeek502/zig-std-lib-fuzzing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248690942,"owners_count":21146233,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fuzz-testing","fuzzing","zig"],"created_at":"2024-10-14T20:06:24.806Z","updated_at":"2025-04-13T09:33:07.196Z","avatar_url":"https://github.com/squeek502.png","language":"Zig","readme":"Fuzzing the Zig standard library\n================================\n\nA set of fuzzers for fuzzing various parts of the [Zig](https://ziglang.org/) standard library. See ['Fuzzing Zig Code Using AFL++'](https://www.ryanliptak.com/blog/fuzzing-zig-code/) for more information about the particular fuzzing setup used.\n\nCurrent fuzzers:\n- `tokenizer` which calls `std.zig.Tokenizer.next` until it gets an `eof` token\n- `parse` which calls `std.zig.Ast.parse` and then `std.zig.Ast.render`\n- `deflate` which calls `std.compress.flate.decompressor().reader().readAllAlloc()`\n- `deflate-puff` which compares the results of `puff.c` to Zig's `std.compress.flate.decompressor`\n- `deflate-roundtrip` which sends the input through `compressor`, then through `decompressor`, and then checks that the output is the same as the input\n- `json` which calls `std.json.parseFromSlice`\n- `sin` which calls `std.math.sin` and compares the result to libc's `sin`/`sinf`\n- `xz` which calls `std.compress.xz.decompress`\n- `xxhash` which compares the results of `xxhash.c` to Zig's `std.hash.xxhash` implementation\n- `zstandard` which calls the `std.compress.zstd` `decode`, `decodeAlloc`, and `decompressStream` APIs.\n- `zstandard-compare` which compares the results of the `zstd` reference implementation to Zig's `std.compress.zstd.decompress.decode` implementation\n- `zstandard-compare-alloc` which compares the results of the `zstd` reference implementation to Zig's `std.compress.zstd.decompress.decodeAlloc` implementation\n- `zstandard-compare-stream` which compares the results of the `zstd` reference implementation to Zig's `std.compress.zstd.decompressStream` implementation\n- `tar` which uses `std.tar.iterator` to simulate an untar operation (but does not write to the filesystem)\n- `tar-fs` which calls `std.tar.pipeToFileSystem` (and actually writes to the filesystem)\n\nNon-`std` fuzzers (requires `-Dzig-src=/path/to/zig/sources`):\n- `markdown` which calls Autodoc's `markdown.Parser` to parse an input line by line\n- `git` which calls `git.indexPack` on a Git packfile\n  - Requires a patch (`fuzzers/git.patch`) to be applied to upstream `git.zig` so I/O can be avoided.\n  - To verify the contents of the input packfile (`small.pack`):\n\n    1. Create a new empty Git repository (`git init`)\n    2. `git unpack-objects \u003cpath/to/small.pack`\n    3. `git fsck` -\u003e note the \"dangling commit\" ID (which matches the commit checked out below)\n    4. `git checkout 0a9b7c28d992347b3e237bb143c052b177ad388f`\n\nRequires [AFL++](https://github.com/AFLplusplus/AFLplusplus) with `afl-clang-lto` to be installed (see [Compiling AFL++](#compiling-afl)).\n\n## Building a fuzzer\n\nRun `zig build fuzz-\u003cfuzzer name\u003e`, e.g. `zig build fuzz-tokenizer`\n\n## Running a fuzzer\n\nThe instrumented fuzzer will be installed to `zig-out/bin/fuzz-\u003cfuzzer name\u003e`. You'll probably also need to run `mkdir outputs` (if you're planning on using `outputs` as an output directory) before fuzzing. Here's a simple example of running the `tokenizer` fuzzer:\n\n```\nafl-fuzz -i inputs/tokenizer -o outputs/tokenizer -x dictionaries/zig.dict -- ./zig-out/bin/fuzz-tokenizer\n```\n\n(the `-x` option is not necessary but using a dictionary is recommended if possible)\n\nSee [AFL++'s 'fuzzing the target' section](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/fuzzing_in_depth.md#3-fuzzing-the-target) for more recommendations to improve fuzzing effectiveness (using multiple cores, etc).\n\n## Debugging crashes\n\nIf a crash is found during fuzzing, the companion `fuzz-\u003cfuzzer name\u003e-debug` executable can be used to debug the crash. For example, for the `tokenizer` fuzzer, a stack trace could be gotten with:\n\n```sh\n$ ./zig-out/bin/fuzz-tokenizer-debug \u003c 'outputs/tokenizer/default/crashes/id:000000,sig:06,src:000908+000906,time:117053,op:splice,rep:16'\nthread 2730086 panic: index out of bounds\n/home/ryan/Programming/zig/zig/build/lib/zig/std/zig/tokenizer.zig:408:34: 0x215131 in std.zig.tokenizer.Tokenizer.next (fuzz-tokenizer-debug)\n            const c = self.buffer[self.index];\n                                 ^\n/home/ryan/Programming/zig/zig/build/lib/zig/std/zig/parse.zig:24:37: 0x20af60 in std.zig.parse.parse (fuzz-tokenizer-debug)\n        const token = tokenizer.next();\n                                    ^\n...\n```\n\nAlternatively, the crash can be debugged via gdb:\n\n```\ngdb -ex 'set args \u003c outputs/tokenizer/default/crashes/id:000000,sig:06,src:000908+000906,time:117053,op:splice,rep:16' ./zig-out/bin/fuzz-tokenizer-debug\n```\n\nOr valgrind:\n\n```\nvalgrind ./zig-out/bin/fuzz-tokenizer-debug \u003c 'outputs/tokenizer/default/crashes/id:000000,sig:06,src:000908+000906,time:117053,op:splice,rep:16'\n```\n\n[`zigescape`](https://github.com/squeek502/zigescape) can also be used to convert inputs into string literals for the creation of test cases (preferrably after using `afl-tmin` to minimize the input).\n\n## Bugs found / fixed\n\n### `std.zig.Tokenizer`\n\n- https://github.com/ziglang/zig/pull/9808\n- https://github.com/ziglang/zig/pull/9809\n\n### `std.compress.flate`\n\n- [https://github.com/ianic/flate/issues](https://github.com/ianic/flate/issues?q=is%3Aissue+is%3Aclosed+author%3Asqueek502) (a bunch of stuff before it was [submitted as a PR](https://github.com/ziglang/zig/pull/18923))\n\n\u003cdetails\u003e\n\u003csummary\u003eobsoleted Deflate implementations\u003c/summary\u003e\n\n### `std.compress.deflate` (second version of Deflate)\n\n- https://github.com/ziglang/zig/pull/10552#issuecomment-1019194395\n\n### `std.compress.deflate` (first version of Deflate)\n\n- https://github.com/ziglang/zig/pull/9849\n- https://github.com/ziglang/zig/pull/9860\n- https://github.com/ziglang/zig/pull/9880\n\n\u003c/details\u003e\n\n### `std.math`\n\n- `sin`: https://github.com/ziglang/zig/issues/9901\n\n### `std.compress.xz`\n\n- https://github.com/ziglang/zig/issues/14500\n\n### `std.compress.zstandard`\n\n- https://github.com/ziglang/zig/pull/14394 (a whole bunch of stuff during the PR process)\n\n### `std.tar`\n\n- https://github.com/ziglang/zig/pull/19038\n\n### In upstream/third-party projects\n\n#### [`facebook/zstd`](https://github.com/facebook/zstd)\n\n- https://github.com/facebook/zstd/issues/3506\n- https://github.com/facebook/zstd/issues/3507\n- https://github.com/facebook/zstd/issues/3508\n- https://github.com/facebook/zstd/issues/3482\n\n---\n\n## Other tools/fuzzers\n\n### `zstandard-verify`\n\nRequires the `decodecorpus` tool from [zstd](https://github.com/facebook/zstd/tree/dev/tests#decodecorpus---tool-to-generate-zstandard-frames-for-decoder-testing) and the `zstandard-verify` tool from this repo (can be built with `zig build tools`). Run the following command to use it to continuously test the `zstandard` Zig decompressor with generated compressed .zst files:\n\n```\n./tools/zstandard-decodecorpus.sh /path/to/decodecorpus ./zig-out/bin/zstandard-verify\n```\n\n## Compiling AFL++\n\n- Clone `https://github.com/AFLplusplus/AFLplusplus` (avoid recursively cloning, avoid initializing submodules--they are *huge* and unnecessary for our purposes)\n- Make sure `llvm-config --version` matches the same version that your Zig uses\n\n```\ncd AFLplusplus\nmake source-only NO_NYX=1\nmake install\n```\n\n(or `sudo make install` if needed)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsqueek502%2Fzig-std-lib-fuzzing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsqueek502%2Fzig-std-lib-fuzzing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsqueek502%2Fzig-std-lib-fuzzing/lists"}