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 /crates | |
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
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ignore/src/gitignore.rs | 11 |
1 files changed, 7 insertions, 4 deletions
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(); |