Skip to content

Commit 10c7eab

Browse files
committed
Fix directory whitelisting.
There was a bug in the translation from a gitignore pattern to a standard glob where `!/dir` wasn't being interpreted as an absolute path. Fixes BurntSushi#67.
1 parent 447505d commit 10c7eab

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

src/gitignore.rs

+6-17
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl GitignoreBuilder {
276276
from: P,
277277
mut line: &str,
278278
) -> Result<(), Error> {
279-
if line.is_empty() {
279+
if line.is_empty() || line.starts_with("#") {
280280
return Ok(());
281281
}
282282
let mut pat = Pattern {
@@ -289,32 +289,21 @@ impl GitignoreBuilder {
289289
let mut opts = glob::MatchOptions::default();
290290
let has_slash = line.chars().any(|c| c == '/');
291291
let is_absolute = line.chars().nth(0).unwrap() == '/';
292-
// If the line starts with an escaped '!', then remove the escape.
293-
// Otherwise, if it starts with an unescaped '!', then this is a
294-
// whitelist pattern.
295-
match line.chars().nth(0) {
296-
Some('#') => return Ok(()),
297-
Some('\\') => {
298-
match line.chars().nth(1) {
299-
Some('!') | Some('#') => {
300-
line = &line[1..];
301-
}
302-
_ => {}
303-
}
304-
}
305-
Some('!') => {
292+
if line.starts_with("\\!") || line.starts_with("\\#") {
293+
line = &line[1..];
294+
} else {
295+
if line.starts_with("!") {
306296
pat.whitelist = true;
307297
line = &line[1..];
308298
}
309-
Some('/') => {
299+
if line.starts_with("/") {
310300
// `man gitignore` says that if a glob starts with a slash,
311301
// then the glob can only match the beginning of a path
312302
// (relative to the location of gitignore). We achieve this by
313303
// simply banning wildcards from matching /.
314304
opts.require_literal_separator = true;
315305
line = &line[1..];
316306
}
317-
_ => {}
318307
}
319308
// If it ends with a slash, then this should only match directories,
320309
// but the slash should otherwise not be used while globbing.

tests/tests.rs

+12
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,18 @@ clean!(regression_65, "xyz", ".", |wd: WorkDir, mut cmd: Command| {
663663
wd.assert_err(&mut cmd);
664664
});
665665

666+
// See: https://github.com/BurntSushi/ripgrep/issues/67
667+
clean!(regression_67, "test", ".", |wd: WorkDir, mut cmd: Command| {
668+
wd.create(".gitignore", "/*\n!/dir");
669+
wd.create_dir("dir");
670+
wd.create_dir("foo");
671+
wd.create("foo/bar", "test");
672+
wd.create("dir/bar", "test");
673+
674+
let lines: String = wd.stdout(&mut cmd);
675+
assert_eq!(lines, "dir/bar:test\n");
676+
});
677+
666678
// See: https://github.com/BurntSushi/ripgrep/issues/20
667679
sherlock!(feature_20, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
668680
cmd.arg("--no-filename");

0 commit comments

Comments
 (0)