1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#![forbid(unsafe_code)]
#[cfg(test)]
mod tests {
// use super::*; // Unused
use crate::{FseMap, Rule, FseOpcode, FseScanner, Violation};
#[test]
fn test_basic_match_record() {
let rules = vec![
Rule::new("apple", FseOpcode::Record(1)),
Rule::new("banana", FseOpcode::Record(2)),
];
let map = FseMap::compile(rules).unwrap();
let mut scanner = FseScanner::new(&map).unwrap();
let input = b"I like apple and banana splits.";
let summary = scanner.scan(input).unwrap();
assert_eq!(summary.pattern_hits, 2);
assert_eq!(summary.rules_recorded, 2);
}
#[test]
fn test_fail_closed_reject() {
let rules = vec![
Rule::new("safe", FseOpcode::Record(1)),
Rule::new("DANGER", FseOpcode::Reject(99)),
];
let map = FseMap::compile(rules).unwrap();
let mut scanner = FseScanner::new(&map).unwrap();
let input = b"This is safe but DANGER resides here.";
let result = scanner.scan(input);
match result {
Err(Violation::PolicyReject { rule_id, span, .. }) => {
assert_eq!(rule_id, 99);
// "DANGER" is 6 bytes.
// Input: "This is safe but DANGER..."
// Index: 012345678901234567890123456
// "T" is 0. "D" is at 17. "R" is at 22. End is 23.
// Let's just check the byte slice matches.
assert_eq!(&input[span], b"DANGER");
}
_ => panic!("Should have rejected!"),
}
}
#[test]
fn test_overlapping_matches() {
// "he" -> Record(1)
// "she" -> Record(2)
// "hers" -> Record(3)
let rules = vec![
Rule::new("he", FseOpcode::Record(1)),
Rule::new("she", FseOpcode::Record(2)),
Rule::new("hers", FseOpcode::Record(3)),
];
let map = FseMap::compile(rules).unwrap();
let mut scanner = FseScanner::new(&map).unwrap();
let input = b"ushers";
let summary = scanner.scan(input).unwrap();
// "she" matches at "..she.."
// "he" matches inside "she" and in "he" of "hers"?
// Aho-Corasick behavior depends on how we iterate.
// We iterate ALL matches at a state.
// "she": Matches "she". Contains "he".
// "hers": Matches "hers". Contains "he".
// We expect multiple hits.
assert!(summary.pattern_hits >= 3);
}
}