Skip to content

Commit d068a33

Browse files
committed
Fuzz options, and make failure print out a test
1 parent 1872bdf commit d068a33

File tree

2 files changed

+66
-17
lines changed

2 files changed

+66
-17
lines changed

fuzz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2018"
99
cargo-fuzz = true
1010

1111
[dependencies]
12-
libfuzzer-sys = "0.4.1"
12+
libfuzzer-sys = { version = "0.4.1", features = ["arbitrary-derive"] }
1313

1414
[dependencies.regex]
1515
path = ".."

fuzz/fuzz_targets/fuzz_regex_match.rs

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,71 @@
11
#![no_main]
22
use libfuzzer_sys::fuzz_target;
33

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+
)
754
}
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);
2170
}
2271
});

0 commit comments

Comments
 (0)