Skip to content

Commit eb2dbaa

Browse files
committed
add dense dfa
1 parent 1be61a5 commit eb2dbaa

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

fuzz/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ path = "fuzz_targets/ast_fuzz_match_bytes.rs"
7171
name = "ast_diff_default"
7272
path = "fuzz_targets/ast_diff_default.rs"
7373

74+
[[bin]]
75+
name = "ast_diff_dense_dfa"
76+
path = "fuzz_targets/ast_diff_dense_dfa.rs"
77+
7478
[[bin]]
7579
name = "ast_diff_nfas"
7680
path = "fuzz_targets/ast_diff_nfas.rs"

fuzz/fuzz_targets/ast_diff_default.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ fn do_fuzz(data: FuzzData) -> Corpus {
2626
let _ = env_logger::try_init();
2727

2828
let pattern = format!("{}", data.ast);
29-
let Ok(re) = RegexBuilder::new(&pattern).size_limit(1 << 20).build() else {
30-
return Corpus::Reject;
31-
};
3229
let config = NFA::config().nfa_size_limit(Some(1 << 20));
3330
let Ok(nfa) = NFA::compiler().configure(config).build(&pattern) else {
3431
return Corpus::Reject;
@@ -38,6 +35,10 @@ fn do_fuzz(data: FuzzData) -> Corpus {
3835
};
3936
let mut cache = baseline.create_cache();
4037

38+
let Ok(re) = RegexBuilder::new(&pattern).size_limit(1 << 20).build() else {
39+
return Corpus::Reject;
40+
};
41+
4142
assert_eq!(
4243
re.is_match(&data.haystack),
4344
baseline.is_match(&mut cache, &data.haystack)
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#![no_main]
2+
3+
use {
4+
libfuzzer_sys::{fuzz_target, Corpus},
5+
regex_automata::{
6+
dfa::{dense::DFA, regex::Builder as RegexBuilder},
7+
nfa::thompson::{pikevm::PikeVM as NfaRegex, NFA},
8+
},
9+
regex_syntax::ast::Ast,
10+
};
11+
12+
#[derive(Eq, PartialEq, arbitrary::Arbitrary)]
13+
struct FuzzData {
14+
ast: Ast,
15+
haystack: String,
16+
}
17+
18+
impl std::fmt::Debug for FuzzData {
19+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20+
let mut builder = f.debug_struct("FuzzData");
21+
builder.field("ast", &format!("{}", self.ast));
22+
builder.field("haystack", &self.haystack);
23+
builder.finish()
24+
}
25+
}
26+
27+
fn do_fuzz(data: FuzzData) -> Corpus {
28+
let _ = env_logger::try_init();
29+
30+
let pattern = format!("{}", data.ast);
31+
let config = NFA::config().nfa_size_limit(Some(1 << 20));
32+
let Ok(nfa) = NFA::compiler().configure(config).build(&pattern) else {
33+
return Corpus::Reject;
34+
};
35+
let Ok(baseline) = NfaRegex::new_from_nfa(nfa) else {
36+
return Corpus::Reject;
37+
};
38+
let mut cache = baseline.create_cache();
39+
40+
let config = DFA::config().dfa_size_limit(Some(1 << 20));
41+
let Ok(re) = RegexBuilder::new().dense(config).build(&pattern) else {
42+
return Corpus::Reject;
43+
};
44+
45+
assert_eq!(
46+
re.is_match(&data.haystack),
47+
baseline.is_match(&mut cache, &data.haystack)
48+
);
49+
let found1 = re.find(&data.haystack);
50+
let found2 = baseline.find(&mut cache, &data.haystack);
51+
if let Some(found1) = found1 {
52+
let found2 = found2.expect("Found in target, but not in baseline!");
53+
assert_eq!(found1.start(), found2.start());
54+
assert_eq!(found1.end(), found2.end());
55+
}
56+
57+
// no captures
58+
59+
Corpus::Keep
60+
}
61+
62+
fuzz_target!(|data: FuzzData| -> Corpus { do_fuzz(data) });

fuzz/fuzz_targets/ast_diff_nfas.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ fn do_fuzz(data: FuzzData) -> Corpus {
3131
let Ok(nfa) = NFA::compiler().configure(config).build(&pattern) else {
3232
return Corpus::Reject;
3333
};
34-
let Ok(backtracker) = BoundedBacktracker::new_from_nfa(nfa.clone()) else {
35-
return Corpus::Reject; };
36-
let mut backtracker_cache = backtracker.create_cache();
37-
let Ok(baseline) = PikeVM::new_from_nfa(nfa) else {
34+
let Ok(baseline) = PikeVM::new_from_nfa(nfa.clone()) else {
3835
return Corpus::Reject;
3936
};
4037
let mut baseline_cache = baseline.create_cache();
4138

39+
let Ok(backtracker) = BoundedBacktracker::new_from_nfa(nfa) else {
40+
return Corpus::Reject;
41+
};
42+
let mut backtracker_cache = backtracker.create_cache();
43+
4244
if let Ok(backtracked) =
4345
backtracker.try_is_match(&mut backtracker_cache, &data.haystack)
4446
{

0 commit comments

Comments
 (0)