Skip to content

Commit

Permalink
fix: Panic on capture groups
Browse files Browse the repository at this point in the history
When an "overall match" collided with capture
group ranges, slicing panicked due to invalid
overlaps.

Closes #71
  • Loading branch information
alexpovel committed Mar 25, 2024
1 parent f55bdf7 commit ea1aa08
Showing 1 changed file with 46 additions and 10 deletions.
56 changes: 46 additions & 10 deletions src/scoping/regex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::ROScopes;
use super::Scoper;
use crate::scoping::scope::subtract;
use crate::RegexPattern;
use crate::GLOBAL_SCOPE;
use log::{debug, trace};
Expand Down Expand Up @@ -87,19 +88,16 @@ impl Scoper for Regex {
subranges.push(group.range());
}

let mut last_end = overall_match.range().start;
for subrange in subranges.into_iter().rev() {
ranges.push(Range {
start: last_end,
end: subrange.start,
});
// Parts of the overall match, but not the capture groups: push as-is
ranges.extend(subtract(vec![overall_match.range()], &subranges));

ranges.extend(shatter(&subrange));

last_end = subrange.end;
}
// Treat the capture groups specially now
subranges
.iter()
.for_each(|subrange| ranges.extend(shatter(subrange)));
}

ranges.sort_by_key(|r| r.start);
debug!("Ranges to scope after regex: {:?}", ranges);
ranges
} else {
Expand Down Expand Up @@ -208,6 +206,44 @@ mod tests {
]
))
)]
#[case(
// https://github.com/alexpovel/srgn/issues/71; this used to panic
r#""error"; "x" => %x, "y" => %y"#,
r"(?P<msg>.+);(?P<structure>.+)",
ScopedView::new(RWScopes(
vec![
RWScope(In(B(r#"""#))),
RWScope(In(B("e"))),
RWScope(In(B("r"))),
RWScope(In(B("r"))),
RWScope(In(B("o"))),
RWScope(In(B("r"))),
RWScope(In(B(r#"""#))),
RWScope(In(B(";"))),
RWScope(In(B(" "))),
RWScope(In(B(r#"""#))),
RWScope(In(B("x"))),
RWScope(In(B(r#"""#))),
RWScope(In(B(" "))),
RWScope(In(B("="))),
RWScope(In(B(">"))),
RWScope(In(B(" "))),
RWScope(In(B("%"))),
RWScope(In(B("x"))),
RWScope(In(B(","))),
RWScope(In(B(" "))),
RWScope(In(B(r#"""#))),
RWScope(In(B("y"))),
RWScope(In(B(r#"""#))),
RWScope(In(B(" "))),
RWScope(In(B("="))),
RWScope(In(B(">"))),
RWScope(In(B(" "))),
RWScope(In(B("%"))),
RWScope(In(B("y"))),
]
))
)]
fn test_regex_scoping(
#[case] input: &str,
#[case] pattern: &str,
Expand Down

0 comments on commit ea1aa08

Please sign in to comment.