Skip to content

Commit

Permalink
[BugFix]: Fix panic occurring for regex with incomplete groupings (#429)
Browse files Browse the repository at this point in the history
* [BugFix]: fix to catch panic when handling regex that contains incomplete groupings

* [Misc]: removed debugging statements
  • Loading branch information
joshfried-aws authored Dec 7, 2023
1 parent 1369f67 commit f624b46
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
27 changes: 26 additions & 1 deletion guard/src/rules/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,39 @@ fn parse_regex_inner(input: Span) -> IResult<Span, Value> {

regex.push_str(fragment);

for c in regex.chars() {
let mut stack = vec![];
let chars = regex.chars().collect::<Vec<_>>();

for (i, c) in chars.iter().enumerate() {
if c.is_control() {
return Err(nom::Err::Error(ParserError {
context: "Could not parse regular expression".to_string(),
kind: ErrorKind::RegexpMatch,
span: input,
}));
}
if *c == '(' {
if i == 0 || *chars.get(i - 1).unwrap() != '\\' {
stack.push(c);
}
} else if *c == ')'
&& (i == 0 || *chars.get(i - 1).unwrap() != '\\')
&& stack.pop().is_none()
{
return Err(nom::Err::Error(ParserError {
context: "Could not parse regular expression".to_string(),
kind: ErrorKind::RegexpMatch,
span: input,
}));
}
}

if !stack.is_empty() {
return Err(nom::Err::Error(ParserError {
context: "Could not parse regular expression".to_string(),
kind: ErrorKind::RegexpMatch,
span: input,
}));
}

return match Regex::try_from(regex.as_str()) {
Expand Down
18 changes: 18 additions & 0 deletions guard/src/rules/parser_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4623,6 +4623,24 @@ fn test_parse_regex_inner_when_regex_is_valid() {
assert!(parse_regex_inner(valid_cmp).is_ok())
}

#[test]
fn test_parse_regex_when_regex_contains_incomplete_group_structure() {
std::env::set_var("RUST_BACKTRACE", "1");

let invalid = r#"/!w(?()"Kuz>/"#;

let invalid_cmp = unsafe { Span::new_from_raw_offset(invalid.len(), 1, invalid, "") };
assert!(parse_regex(invalid_cmp).is_err());
}

#[test]
fn test_parse_regex_when_regex_contains_complete_group_structure_and_escaped_opening_paren() {
let invalid = r#"/!w\(?()"Kuz>/"#;

let invalid_cmp = unsafe { Span::new_from_raw_offset(invalid.len(), 1, invalid, "") };
assert!(parse_regex(invalid_cmp).is_ok());
}

#[test]
fn test_parse_regex_when_regex_contains_control_characters() {
let invalid = r#"t(/(FF()!t (?(
Expand Down

0 comments on commit f624b46

Please sign in to comment.