1
0
зеркало из https://github.com/glebtv/tui-textarea.git synced 2026-09-03 14:26:17 +03:00

derive Arbitrary to generate better random inputs on fuzzing

Этот коммит содержится в:
rhysd
2022-06-17 13:20:14 +09:00
родитель 30bd068b34
Коммит f9a07f6c33
3 изменённых файлов: 58 добавлений и 30 удалений

Просмотреть файл

@@ -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
```

Просмотреть файл

@@ -10,7 +10,7 @@ cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4"
arbitrary = "1"
arbitrary = { version = "1", features = ["derive"] }
[dependencies.tui-textarea]
path = ".."

Просмотреть файл

@@ -6,38 +6,66 @@ use std::iter;
use std::str;
use tui_textarea::{Input, Key, TextArea};
fn arbitrary_input(u: &mut Unstructured) -> Result<Input> {
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<ArbitraryKey> 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<ArbitraryInput> 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::<Result<_>>()?;
let text = <&str>::arbitrary(&mut u)?;