We only generate *valid* sequences of API calls. To do this, we keep track of what objects we've already created in earlier API calls via the `Scope` struct. To generate even-more-pathological sequences of API calls, we use [swarm testing]: > In swarm testing, the usual practice of potentially including all features > in every test case is abandoned. Rather, a large “swarm” of randomly > generated configurations, each of which omits some features, is used, with > configurations receiving equal resources. [swarm testing]: https://www.cs.utah.edu/~regehr/papers/swarm12.pdf There are more public APIs and instance introspection APIs that we have than this fuzzer exercises right now. We will need a better generator of valid Wasm than `wasm-opt -ttf` to really get the most out of those currently-unexercised APIs, since the Wasm modules generated by `wasm-opt -ttf` don't import and export a huge variety of things.
44 lines
1.3 KiB
Rust
44 lines
1.3 KiB
Rust
//! Test case generators.
|
|
//!
|
|
//! Test case generators take raw, unstructured input from a fuzzer
|
|
//! (e.g. libFuzzer) and translate that into a structured test case (e.g. a
|
|
//! valid Wasm binary).
|
|
//!
|
|
//! These are generally implementations of the `Arbitrary` trait, or some
|
|
//! wrapper over an external tool, such that the wrapper implements the
|
|
//! `Arbitrary` trait for the wrapped external tool.
|
|
|
|
pub mod api;
|
|
|
|
use arbitrary::{Arbitrary, Unstructured};
|
|
use std::fmt;
|
|
|
|
/// A Wasm test case generator that is powered by Binaryen's `wasm-opt -ttf`.
|
|
#[derive(Clone)]
|
|
pub struct WasmOptTtf {
|
|
/// The raw, encoded Wasm bytes.
|
|
pub wasm: Vec<u8>,
|
|
}
|
|
|
|
impl fmt::Debug for WasmOptTtf {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"WasmOptTtf {{ wasm: wat::parse_str(r###\"\n{}\n\"###).unwrap() }}",
|
|
wasmprinter::print_bytes(&self.wasm).expect("valid wasm should always disassemble")
|
|
)
|
|
}
|
|
}
|
|
|
|
impl Arbitrary for WasmOptTtf {
|
|
fn arbitrary<U>(input: &mut U) -> Result<Self, U::Error>
|
|
where
|
|
U: Unstructured + ?Sized,
|
|
{
|
|
let seed: Vec<u8> = Arbitrary::arbitrary(input)?;
|
|
let module = binaryen::tools::translate_to_fuzz_mvp(&seed);
|
|
let wasm = module.write();
|
|
Ok(WasmOptTtf { wasm })
|
|
}
|
|
}
|