supercode_runtime/
policy.rs1pub fn glob_match(pattern: &str, text: &str) -> bool {
9 let pattern = pattern.as_bytes();
10 let text = text.as_bytes();
11 let (mut pattern_index, mut text_index) = (0usize, 0usize);
12 let mut star: Option<(usize, usize)> = None;
13
14 while text_index < text.len() {
15 if pattern_index < pattern.len() && pattern[pattern_index] == b'*' {
16 star = Some((pattern_index, text_index));
17 pattern_index += 1;
18 } else if pattern_index < pattern.len() && pattern[pattern_index] == text[text_index] {
19 pattern_index += 1;
20 text_index += 1;
21 } else if let Some((star_pattern_index, star_text_index)) = star {
22 let next_text_index = star_text_index + 1;
23 star = Some((star_pattern_index, next_text_index));
24 pattern_index = star_pattern_index + 1;
25 text_index = next_text_index;
26 } else {
27 return false;
28 }
29 }
30 while pattern_index < pattern.len() && pattern[pattern_index] == b'*' {
31 pattern_index += 1;
32 }
33 pattern_index == pattern.len()
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn exact_prefix_suffix_and_middle_forms() {
42 assert!(glob_match("bash", "bash"));
43 assert!(glob_match("bash*", "bash_tool"));
44 assert!(glob_match("*_write", "edit_write"));
45 assert!(glob_match("mcp__*__search", "mcp__github__search"));
46 assert!(!glob_match("bash", "bash_tool"));
47 }
48
49 #[test]
50 fn pathological_star_pattern_is_non_recursive() {
51 let pattern = "*a*a*a*a*a*a*a*a*a*a*b";
52 let text = "a".repeat(100_000);
53 assert!(!glob_match(pattern, &text));
54 }
55}