Skip to content

Commit

Permalink
ignore: fix gitignore parsing bug for trailing \/
Browse files Browse the repository at this point in the history
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
  • Loading branch information
BurntSushi committed Jun 14, 2022
1 parent eb4b389 commit 9f0e88b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
13.0.1
======
TBD
===
Unreleased changes. Release notes have not yet been written.

Bug fixes:
Expand All @@ -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)
Expand Down
11 changes: 7 additions & 4 deletions crates/ignore/src/gitignore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
8 changes: 8 additions & 0 deletions tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

0 comments on commit 9f0e88b

Please sign in to comment.