diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0713ed1..dc12a2b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,5 +20,5 @@ To run fuzzer: [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) is necessary. ```sh -cargo fuzz run edit +cargo +nightly fuzz run edit ``` diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 97bd3b7..f9d338e 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -10,7 +10,7 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.4" -arbitrary = "1" +arbitrary = { version = "1", features = ["derive"] } [dependencies.tui-textarea] path = ".." diff --git a/fuzz/fuzz_targets/edit.rs b/fuzz/fuzz_targets/edit.rs index b00b1ce..1480ea8 100644 --- a/fuzz/fuzz_targets/edit.rs +++ b/fuzz/fuzz_targets/edit.rs @@ -6,38 +6,66 @@ use std::iter; use std::str; use tui_textarea::{Input, Key, TextArea}; -fn arbitrary_input(u: &mut Unstructured) -> Result { - let i = u8::arbitrary(u)? % 15; - let key = match i { - 1 => Key::Backspace, - 2 => Key::Enter, - 3 => Key::Left, - 4 => Key::Right, - 5 => Key::Up, - 6 => Key::Down, - 7 => Key::Tab, - 8 => Key::Delete, - 9 => Key::Home, - 10 => Key::End, - 11 => Key::PageUp, - 12 => Key::PageDown, - 13 => Key::Esc, - 14 => Key::Null, - _ => match char::arbitrary(u)? { - '\n' | '\r' => Key::Enter, - c => Key::Char(c), - }, - }; - Ok(Input { - key, - ctrl: bool::arbitrary(u)?, - alt: bool::arbitrary(u)?, - }) +macro_rules! arbitrary_key_enum { + ($($p:ident$(($x:ident))?,)+) => { + + #[derive(Arbitrary)] + enum ArbitraryKey { + $( + $p$(($x))?, + )+ + } + + impl From for Key { + fn from(k: ArbitraryKey) -> Key { + match k { + $( + ArbitraryKey::$p$(($x))? => Key::$p$(($x))?, + )+ + } + } + } + } +} + +arbitrary_key_enum!( + Char(char), + Backspace, + Enter, + Left, + Right, + Up, + Down, + Tab, + Delete, + Home, + End, + PageUp, + PageDown, + Esc, + Null, +); + +#[derive(Arbitrary)] +struct ArbitraryInput { + key: ArbitraryKey, + ctrl: bool, + alt: bool, +} + +impl From for Input { + fn from(i: ArbitraryInput) -> Input { + Input { + key: i.key.into(), + ctrl: i.ctrl, + alt: i.alt, + } + } } fn fuzz(data: &[u8]) -> Result<()> { let mut u = Unstructured::new(data); - let inputs: Vec<_> = iter::repeat_with(|| arbitrary_input(&mut u)) + let inputs: Vec<_> = iter::repeat_with(|| ArbitraryInput::arbitrary(&mut u)) .take(10) .collect::>()?; let text = <&str>::arbitrary(&mut u)?;