From fbb2cfed28d68b220e51c0fe8db9d89a4516aab6 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Mon, 31 May 2021 19:52:26 -0400 Subject: printer: trim line terminator before doing replacements This is basically the same bug as #1401, but applied to replacements instead of --only-matching. Fixes #1739 --- CHANGELOG.md | 2 ++ crates/printer/src/util.rs | 8 +++++++- tests/regression.rs | 7 +++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afdcfd2d..360b1c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,8 @@ Bug fixes: * [BUG #1277](https://github.com/BurntSushi/ripgrep/issues/1277): Document cygwin path translation behavior in the FAQ. +* [BUG #1739](https://github.com/BurntSushi/ripgrep/issues/1739): + Fix bug where replacements were buggy if the regex matched a line terminator. * [BUG #1311](https://github.com/BurntSushi/ripgrep/issues/1311): Fix multi-line bug where a search & replace for `\n` didn't work as expected. * [BUG #1401](https://github.com/BurntSushi/ripgrep/issues/1401): diff --git a/crates/printer/src/util.rs b/crates/printer/src/util.rs index e19d4a8b..68693d34 100644 --- a/crates/printer/src/util.rs +++ b/crates/printer/src/util.rs @@ -68,7 +68,13 @@ impl Replacer { subject = &subject[..range.end + MAX_LOOK_AHEAD]; } } else { - subject = &subject[..range.end]; + // When searching a single line, we should remove the line + // terminator. Otherwise, it's possible for the regex (via + // look-around) to observe the line terminator and not match + // because of it. + let mut m = Match::new(0, range.end); + trim_line_terminator(searcher, subject, &mut m); + subject = &subject[..m.end()]; } { let &mut Space { ref mut dst, ref mut caps, ref mut matches } = diff --git a/tests/regression.rs b/tests/regression.rs index cd14d5e4..c905e736 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -945,6 +945,13 @@ rgtest!(r1638, |dir: Dir, mut cmd: TestCommand| { eqnice!("foo:1:1:x\n", cmd.arg("--column").arg("x").stdout()); }); +// See: https://github.com/BurntSushi/ripgrep/issues/1739 +rgtest!(r1739_replacement_lineterm_match, |dir: Dir, mut cmd: TestCommand| { + dir.create("test", "a\n"); + cmd.args(&[r"-r${0}f", r".*", "test"]); + eqnice!("af\n", cmd.stdout()); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/1765 rgtest!(r1765, |dir: Dir, mut cmd: TestCommand| { dir.create("test", "\n"); -- cgit v1.2.3