Skip to content

Skepfyr/rust-parser-fuzz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust parser differential fuzzer

This is a fuzzing application for comparing Rust parsers, currently rustc, syn, and rust-analyzer.

It uses the brilliant cargo-fuzz tool to generate random(-ish) files and attempts to parse them with every parser. It then converts the resulting ASTs into a common representation and compares them, it reports a bug if any of the parsers disagree on whether the code is valid or not, or if they produce different ASTs for valid code.

Usage

This project is slightly finnicky to build due to it depending on rustc.

  1. Source the .envrc file, it contains a couple of environment variables required to build rustc.
  2. I'd strongly recommend [patch]-ing the rustc dependency in Cargo.toml to point to a local checkout of rustc, as cargo will clone a new copy into your cache which takes a while and takes a bunch of space. You can copy this section to .cargo/config.toml to persist it without committing to the repo.
  3. You need to use a recent version of rust to build rustc, I recommend using the same version that the rustc checkout is (which should be latest stable).
  4. If you want to actually fuzz, install cargo-fuzz with cargo install cargo-fuzz. You probably want to seed the corpus with a bunch of rust code too. The best source I've found is to copy all the rustc testsuite, something like cp <rust checkout>/tests/ui/**/*.rs fuzz/corpus/diff/.

To fuzz the parsers run: cargo fuzz run diff --no-cfg-fuzzing (proc-macro2 does weird things if cfg(fuzzing) is enabled).
To run against the fuzz corpus run: cargo run --release (debug will probably stack overflow).
To test a specific file run: cargo run path/to/file.rs.\

Reporting bugs upstream

For now, please don't report bugs found by this tool to the parser projects directly, as it finds a lot of edge cases and I don't want to spam them. Also, parsers like rust-analyzer intentionally parse some invalid Rust code for better IDE support so a bunch of the bugs will be false positives.

Repo overview

The repo isn't too big so I hope it's approachable, but a quick overview:

  • src/lib.rs: The main entry point that can diff parsers. It's used by fuzz/fuzz_targets/diff.rs and src/main.rs.
  • src/ast.rs: The common AST representation.
  • src/<parser>: Each supported parser has its own module with parsing and AST conversion code.
    • mod.rs: Parser implementation and a bunch of filters that detect known bugs and cause the fuzzer to skip that bug without erroring out, so we can continue fuzzing without fixing all the bugs.
    • convert.rs: Conversion from parser-specific AST to common representation.

License

Licensed under either of

at your option.

Contribution

This project welcomes contributions and suggestions, just open an issue or pull request!

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

A fuzzing application for comparing Rust parsers

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages