1 #![no_main]
2 
3 use libfuzzer_sys::arbitrary::{Result, Unstructured};
4 use libfuzzer_sys::fuzz_target;
5 use wasmtime_fuzzing::{generators, oracles};
6 
7 fuzz_target!(|data: &[u8]| {
8     // errors in `run` have to do with not enough input in `data`, which we
9     // ignore here since it doesn't affect how we'd like to fuzz.
10     let _ = run_one(data);
11 });
12 
run_one(data: &[u8]) -> Result<()>13 fn run_one(data: &[u8]) -> Result<()> {
14     let mut u = Unstructured::new(data);
15     let mut config: generators::Config = u.arbitrary()?;
16 
17     // Try to ensure imports/exports/etc are generated by adding one to the
18     // minimums/maximums.
19     config.module_config.config.min_types = 1;
20     config.module_config.config.max_types += 1;
21     config.module_config.config.min_imports = 1;
22     config.module_config.config.max_imports += 1;
23     config.module_config.config.min_funcs = 1;
24     config.module_config.config.max_funcs += 1;
25     config.module_config.config.min_exports = 1;
26     config.module_config.config.max_exports += 1;
27 
28     // Use the fuzz input to select an async strategy.
29     config.enable_async(&mut u)?;
30 
31     let mut poll_amts = Vec::with_capacity(u.arbitrary_len::<u32>()?);
32     for _ in 0..poll_amts.capacity() {
33         poll_amts.push(u.int_in_range(0..=10_000)?);
34     }
35     let module = config.module_config.generate(&mut u, None)?;
36     oracles::call_async(&module.to_bytes(), &config, &poll_amts);
37 
38     Ok(())
39 }
40