diff --git a/crates/matcher/src/lib.rs b/crates/matcher/src/lib.rs index 92365efb..5b43b0d8 100644 --- a/crates/matcher/src/lib.rs +++ b/crates/matcher/src/lib.rs @@ -116,7 +116,7 @@ impl Match { /// This method panics if `start > self.end`. #[inline] pub fn with_start(&self, start: usize) -> Match { - assert!(start <= self.end); + assert!(start <= self.end, "{} is not <= {}", start, self.end); Match { start, ..*self } } @@ -128,7 +128,7 @@ impl Match { /// This method panics if `self.start > end`. #[inline] pub fn with_end(&self, end: usize) -> Match { - assert!(self.start <= end); + assert!(self.start <= end, "{} is not <= {}", self.start, end); Match { end, ..*self } } diff --git a/crates/regex/src/word.rs b/crates/regex/src/word.rs index d73dd6ca..aa08164b 100644 --- a/crates/regex/src/word.rs +++ b/crates/regex/src/word.rs @@ -111,8 +111,15 @@ impl WordMatcher { } let (_, slen) = bstr::decode_utf8(&haystack[cand]); let (_, elen) = bstr::decode_last_utf8(&haystack[cand]); - cand = - cand.with_start(cand.start() + slen).with_end(cand.end() - elen); + let new_start = cand.start() + slen; + let new_end = cand.end() - elen; + // This occurs the original regex can match the empty string. In this + // case, just bail instead of trying to get it right here since it's + // likely a pathological case. + if new_start > new_end { + return Err(()); + } + cand = cand.with_start(new_start).with_end(new_end); if self.original.is_match(&haystack[cand]) { Ok(Some(cand)) } else { diff --git a/tests/regression.rs b/tests/regression.rs index c905e736..e35e953f 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -1029,3 +1029,11 @@ rgtest!(r1878, |dir: Dir, _: TestCommand| { let args = &["-U", "--mmap", r"\Abaz", "test"]; dir.command().args(args).assert_err(); }); + +// See: https://github.com/BurntSushi/ripgrep/issues/1891 +rgtest!(r1891, |dir: Dir, mut cmd: TestCommand| { + dir.create("test", "\n##\n"); + // N.B. We use -o here to force the issue to occur, which seems to only + // happen when each match needs to be detected. + eqnice!("1:\n2:\n2:\n", cmd.args(&["-won", "", "test"]).stdout()); +});