Path: blob/main/fuzz/fuzz_targets/table_ops.rs
1690 views
#![no_main]12use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured};3use libfuzzer_sys::{fuzz_mutator, fuzz_target, fuzzer_mutate};4use mutatis::Session;5use postcard::{from_bytes, to_slice};6use rand::{Rng, SeedableRng};7use wasmtime_fuzzing::generators::table_ops::TableOps;8use wasmtime_fuzzing::oracles::table_ops;910fuzz_target!(|data: &[u8]| {11let Ok((seed, ops)) = postcard::from_bytes::<(u64, TableOps)>(data) else {12return;13};1415let mut buf = [0u8; 1024];16let mut rng = rand::rngs::StdRng::seed_from_u64(seed);17rng.fill(&mut buf);1819let u = Unstructured::new(&buf);20let Ok(config) = wasmtime_fuzzing::generators::Config::arbitrary_take_rest(u) else {21return;22};2324let _ = table_ops(config, ops);25});2627fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {28let _ = env_logger::try_init();2930// With probability of about 1/8, use default mutator31if seed.count_ones() % 8 == 0 {32return fuzzer_mutate(data, size, max_size);33}3435// Try to decode using postcard; fallback to default input on failure36let mut tuple: (u64, TableOps) = from_bytes(&data[..size]).ok().unwrap_or_default();3738let mut session = Session::new().seed(seed.into()).shrink(max_size < size);3940if session.mutate(&mut tuple).is_ok() {41loop {42if let Ok(encoded) = to_slice(&tuple, data) {43return encoded.len();44}4546// Attempt to shrink ops if encoding fails (e.g., buffer too small)47if tuple.1.pop() {48continue;49}5051break;52}53}5455// Fallback to default libfuzzer mutator56fuzzer_mutate(data, size, max_size)57});585960