|
1 | 1 | #![no_main]
|
2 | 2 | use libfuzzer_sys::fuzz_target;
|
3 | 3 |
|
4 |
| -fuzz_target!(|data: &[u8]| { |
5 |
| - if data.len() < 2 { |
6 |
| - return; |
| 4 | +use libfuzzer_sys::arbitrary; |
| 5 | + |
| 6 | +#[derive(arbitrary::Arbitrary)] |
| 7 | +struct FuzzCase<'a> { |
| 8 | + pattern: &'a str, |
| 9 | + input: &'a str, |
| 10 | + case_insensitive: bool, |
| 11 | + multi_line: bool, |
| 12 | + dot_matches_new_line: bool, |
| 13 | + swap_greed: bool, |
| 14 | + ignore_whitespace: bool, |
| 15 | + unicode: bool, |
| 16 | + octal: bool, |
| 17 | +} |
| 18 | + |
| 19 | +impl std::fmt::Debug for FuzzCase<'_> { |
| 20 | + fn fmt( |
| 21 | + &self, |
| 22 | + fmt: &mut std::fmt::Formatter, |
| 23 | + ) -> Result<(), std::fmt::Error> { |
| 24 | + let Self { |
| 25 | + pattern, |
| 26 | + case_insensitive, |
| 27 | + multi_line, |
| 28 | + dot_matches_new_line, |
| 29 | + swap_greed, |
| 30 | + ignore_whitespace, |
| 31 | + unicode, |
| 32 | + octal, |
| 33 | + input, |
| 34 | + } = self; |
| 35 | + |
| 36 | + write!( |
| 37 | + fmt, |
| 38 | + r#" |
| 39 | +let r = regex::RegexBuilder::new({pattern:?}) |
| 40 | + .case_insensitive({case_insensitive:?}) |
| 41 | + .multi_line({multi_line:?}) |
| 42 | + .dot_matches_new_line({dot_matches_new_line:?}) |
| 43 | + .swap_greed({swap_greed:?}) |
| 44 | + .ignore_whitespace({ignore_whitespace:?}) |
| 45 | + .unicode({unicode:?}) |
| 46 | + .octal({octal:?}) |
| 47 | + .build(); |
| 48 | +
|
| 49 | +if let Ok(re) = r {{ |
| 50 | + re.is_match({input:?}); |
| 51 | +}} |
| 52 | + "# |
| 53 | + ) |
7 | 54 | }
|
8 |
| - let split_point = data[0] as usize; |
9 |
| - if let Ok(data) = std::str::from_utf8(&data[1..]) { |
10 |
| - use std::cmp::max; |
11 |
| - // split data into regular expression and actual input to search through |
12 |
| - let len = data.chars().count(); |
13 |
| - let split_off_point = max(split_point, 1) % len as usize; |
14 |
| - let char_index = data.char_indices().nth(split_off_point); |
15 |
| - if let Some((char_index, _)) = char_index { |
16 |
| - let (pattern, input) = data.split_at(char_index); |
17 |
| - if let Ok(re) = regex::Regex::new(pattern) { |
18 |
| - re.is_match(input); |
19 |
| - } |
20 |
| - } |
| 55 | +} |
| 56 | + |
| 57 | +fuzz_target!(|case: FuzzCase| { |
| 58 | + let r = regex::RegexBuilder::new(case.pattern) |
| 59 | + .case_insensitive(case.case_insensitive) |
| 60 | + .multi_line(case.multi_line) |
| 61 | + .dot_matches_new_line(case.dot_matches_new_line) |
| 62 | + .swap_greed(case.swap_greed) |
| 63 | + .ignore_whitespace(case.ignore_whitespace) |
| 64 | + .unicode(case.unicode) |
| 65 | + .octal(case.octal) |
| 66 | + .build(); |
| 67 | + |
| 68 | + if let Ok(re) = r { |
| 69 | + re.is_match(case.input); |
21 | 70 | }
|
22 | 71 | });
|
0 commit comments