From 9f0e88bcb14e02da1b88872435b17d74786640b5 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Tue, 14 Jun 2022 10:38:32 -0400 Subject: ignore: fix gitignore parsing bug for trailing \/ When a glob pattern ended with a \/, and since we permit backslash escapes, the glob parser gave a "dangling escape" error. Which is weird, because the \ is clearly not dangling. The issue is that the layer above the glob parser, the gitignore parser, was stripping the trailing / so that it wouldn't be part of the matching logic. Of course, stripping the trailing / while it is escaped without removing the backslash escape is wrong. So we do that here. Fixes #2236 --- CHANGELOG.md | 6 ++++-- crates/ignore/src/gitignore.rs | 11 +++++++---- tests/regression.rs | 8 ++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba427f92..1e11a8ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -13.0.1 -====== +TBD +=== Unreleased changes. Release notes have not yet been written. Bug fixes: @@ -8,6 +8,8 @@ Bug fixes: Fix bug when using `-w` with a regex that can match the empty string. * [BUG #1911](https://github.com/BurntSushi/ripgrep/issues/1911): Disable mmap searching in all non-64-bit environments. +* [BUG #2236](https://github.com/BurntSushi/ripgrep/issues/2236): + Fix gitignore parsing bug where a trailing `\/` resulted in an error. 13.0.0 (2021-06-12) diff --git a/crates/ignore/src/gitignore.rs b/crates/ignore/src/gitignore.rs index 7922651c..3c7ba5e6 100644 --- a/crates/ignore/src/gitignore.rs +++ b/crates/ignore/src/gitignore.rs @@ -474,10 +474,13 @@ impl GitignoreBuilder { } // If it ends with a slash, then this should only match directories, // but the slash should otherwise not be used while globbing. - if let Some((i, c)) = line.char_indices().rev().nth(0) { - if c == '/' { - glob.is_only_dir = true; - line = &line[..i]; + if line.as_bytes().last() == Some(&b'/') { + glob.is_only_dir = true; + line = &line[..line.len() - 1]; + // If the slash was escaped, then remove the escape. + // See: https://github.com/BurntSushi/ripgrep/issues/2236 + if line.as_bytes().last() == Some(&b'\\') { + line = &line[..line.len() - 1]; } } glob.actual = line.to_string(); diff --git a/tests/regression.rs b/tests/regression.rs index f777ed1c..e2c56968 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -1118,3 +1118,11 @@ pipc () { # [-h] [-U|-u [,...]] [...] [--