Skip to content

Commit cd05a24

Browse files
committed
input: fix infinite loop regression
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
1 parent 9687986 commit cd05a24

File tree

4 files changed

+22
-7
lines changed

4 files changed

+22
-7
lines changed

Diff for: CHANGELOG.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
1.1.6 (2019-04-16)
2+
==================
3+
This release fixes a regression introduced by a bug fix (for
4+
[BUG #557](https://github.com/rust-lang/regex/issues/557)) which could cause
5+
the regex engine to enter an infinite loop. This bug was originally
6+
[reported against ripgrep](https://github.com/BurntSushi/ripgrep/issues/1247).
7+
8+
19
1.1.5 (2019-04-01)
210
==================
3-
This releases fixes a bug in regex's dependency specification where it requires
11+
This release fixes a bug in regex's dependency specification where it requires
412
a newer version of regex-syntax, but this wasn't communicated correctly in the
513
Cargo.toml. This would have been caught by a minimal version check, but this
614
check was disabled because the `rand` crate itself advertises incorrect

Diff for: src/backtrack.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
9898
slots: &'s mut [Slot],
9999
input: I,
100100
start: usize,
101-
end: usize,
101+
end: usize,
102102
) -> bool {
103103
let mut cache = cache.borrow_mut();
104104
let cache = &mut cache.backtrack;
@@ -171,7 +171,7 @@ impl<'a, 'm, 'r, 's, I: Input> Bounded<'a, 'm, 'r, 's, I> {
171171
if matched && self.prog.matches.len() == 1 {
172172
return true;
173173
}
174-
if at.pos() == end {
174+
if at.pos() == end || at.is_end() {
175175
break;
176176
}
177177
at = self.input.at(at.next_pos());

Diff for: src/pikevm.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl<'r, I: Input> Fsm<'r, I> {
107107
quit_after_match: bool,
108108
input: I,
109109
start: usize,
110-
end: usize,
110+
end: usize,
111111
) -> bool {
112112
let mut cache = cache.borrow_mut();
113113
let cache = &mut cache.pikevm;
@@ -125,7 +125,7 @@ impl<'r, I: Input> Fsm<'r, I> {
125125
slots,
126126
quit_after_match,
127127
at,
128-
end,
128+
end,
129129
)
130130
}
131131

@@ -137,7 +137,7 @@ impl<'r, I: Input> Fsm<'r, I> {
137137
slots: &mut [Slot],
138138
quit_after_match: bool,
139139
mut at: InputAt,
140-
end: usize,
140+
end: usize,
141141
) -> bool {
142142
let mut matched = false;
143143
let mut all_matched = false;
@@ -215,7 +215,7 @@ impl<'r, I: Input> Fsm<'r, I> {
215215
}
216216
}
217217
}
218-
if at.pos() == end {
218+
if at.pos() == end || at.is_end() {
219219
break;
220220
}
221221
at = at_next;

Diff for: tests/regression.rs

+7
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,10 @@ mat!(
141141
"samwise",
142142
Some((0, 7))
143143
);
144+
145+
// See: https://github.com/BurntSushi/ripgrep/issues/1247
146+
#[test]
147+
fn regression_nfa_stops1() {
148+
let re = ::regex::bytes::Regex::new(r"\bs(?:[ab])").unwrap();
149+
assert_eq!(0, re.find_iter(b"s\xE4").count());
150+
}

0 commit comments

Comments
 (0)