Skip to content

Commit

Permalink
input: fix infinite loop regression
Browse files Browse the repository at this point in the history
This fixes a bug introduced by a bug fix for #557. In particular, the
termination condition wasn't exactly right, and this appears to have
slipped through the test suite. This probably reveals a hole in our test
suite, which is specifically the testing of Unicode regexes with
bytes::Regex on invalid UTF-8.

This bug was originally reported against ripgrep:
BurntSushi/ripgrep#1247
  • Loading branch information
BurntSushi committed Apr 16, 2019
1 parent 9687986 commit cd05a24
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 7 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
1.1.6 (2019-04-16)
==================
This release fixes a regression introduced by a bug fix (for
[BUG #557](https://github.com/rust-lang/regex/issues/557)) which could cause
the regex engine to enter an infinite loop. This bug was originally
[reported against ripgrep](https://github.com/BurntSushi/ripgrep/issues/1247).


1.1.5 (2019-04-01)
==================
This releases fixes a bug in regex's dependency specification where it requires
This release fixes a bug in regex's dependency specification where it requires
a newer version of regex-syntax, but this wasn't communicated correctly in the
Cargo.toml. This would have been caught by a minimal version check, but this
check was disabled because the `rand` crate itself advertises incorrect
Expand Down
4 changes: 2 additions & 2 deletions src/backtrack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
slots: &'s mut [Slot],
input: I,
start: usize,
end: usize,
end: usize,
) -> bool {
let mut cache = cache.borrow_mut();
let cache = &mut cache.backtrack;
Expand Down Expand Up @@ -171,7 +171,7 @@ impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
if matched && self.prog.matches.len() == 1 {
return true;
}
if at.pos() == end {
if at.pos() == end || at.is_end() {
break;
}
at = self.input.at(at.next_pos());
Expand Down
8 changes: 4 additions & 4 deletions src/pikevm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<'r, I: Input> Fsm<'r, I> {
quit_after_match: bool,
input: I,
start: usize,
end: usize,
end: usize,
) -> bool {
let mut cache = cache.borrow_mut();
let cache = &mut cache.pikevm;
Expand All @@ -125,7 +125,7 @@ impl<'r, I: Input> Fsm<'r, I> {
slots,
quit_after_match,
at,
end,
end,
)
}

Expand All @@ -137,7 +137,7 @@ impl<'r, I: Input> Fsm<'r, I> {
slots: &mut [Slot],
quit_after_match: bool,
mut at: InputAt,
end: usize,
end: usize,
) -> bool {
let mut matched = false;
let mut all_matched = false;
Expand Down Expand Up @@ -215,7 +215,7 @@ impl<'r, I: Input> Fsm<'r, I> {
}
}
}
if at.pos() == end {
if at.pos() == end || at.is_end() {
break;
}
at = at_next;
Expand Down
7 changes: 7 additions & 0 deletions tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,10 @@ mat!(
"samwise",
Some((0, 7))
);

// See: https://github.com/BurntSushi/ripgrep/issues/1247
#[test]
fn regression_nfa_stops1() {
let re = ::regex::bytes::Regex::new(r"\bs(?:[ab])").unwrap();
assert_eq!(0, re.find_iter(b"s\xE4").count());
}

0 comments on commit cd05a24

Please sign in to comment.