diff options
author | Andrew Gallant <jamslam@gmail.com> | 2022-06-14 10:38:32 -0400 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2022-06-14 10:40:37 -0400 |
commit | 9f0e88bcb14e02da1b88872435b17d74786640b5 (patch) | |
tree | 64db992cebfe68507804cd157c8e3d4a04bb2531 | |
parent | eb4b38984622f9b7c05f7e9cfd9bfa3d82cc881f (diff) |
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
-rw-r--r-- | CHANGELOG.md | 6 | ||||
-rw-r--r-- | crates/ignore/src/gitignore.rs | 11 | ||||
-rw-r--r-- | 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 <pkgspec>[,<pkgspec>...]] [<reqs-in>...] [-- <pip-compi let expected = " [-h] [-U|-u <pkgspec>[,<pkgspec>...]] [<reqs-in>...] [-- <pip-compile-arg>...]\n"; eqnice!(expected, cmd.stdout()); }); + +// See: https://github.com/BurntSushi/ripgrep/issues/2236 +rgtest!(r2236, |dir: Dir, mut cmd: TestCommand| { + dir.create(".ignore", r"foo\/"); + dir.create_dir("foo"); + dir.create("foo/bar", "test\n"); + cmd.args(&["test"]).assert_err(); +}); |