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 #67.
This commit is contained in:
Andrew Gallant
2016-09-24 20:10:26 -04:00
parent 872a107658
commit b941c10b90
2 changed files with 18 additions and 17 deletions

View File

@@ -276,7 +276,7 @@ impl GitignoreBuilder {
from: P, from: P,
mut line: &str, mut line: &str,
) -> Result<(), Error> { ) -> Result<(), Error> {
if line.is_empty() { if line.is_empty() || line.starts_with("#") {
return Ok(()); return Ok(());
} }
let mut pat = Pattern { let mut pat = Pattern {
@@ -289,24 +289,14 @@ impl GitignoreBuilder {
let mut opts = glob::MatchOptions::default(); let mut opts = glob::MatchOptions::default();
let has_slash = line.chars().any(|c| c == '/'); let has_slash = line.chars().any(|c| c == '/');
let is_absolute = line.chars().nth(0).unwrap() == '/'; let is_absolute = line.chars().nth(0).unwrap() == '/';
// If the line starts with an escaped '!', then remove the escape. if line.starts_with("\\!") || line.starts_with("\\#") {
// Otherwise, if it starts with an unescaped '!', then this is a line = &line[1..];
// whitelist pattern. } else {
match line.chars().nth(0) { if line.starts_with("!") {
Some('#') => return Ok(()),
Some('\\') => {
match line.chars().nth(1) {
Some('!') | Some('#') => {
line = &line[1..];
}
_ => {}
}
}
Some('!') => {
pat.whitelist = true; pat.whitelist = true;
line = &line[1..]; line = &line[1..];
} }
Some('/') => { if line.starts_with("/") {
// `man gitignore` says that if a glob starts with a slash, // `man gitignore` says that if a glob starts with a slash,
// then the glob can only match the beginning of a path // then the glob can only match the beginning of a path
// (relative to the location of gitignore). We achieve this by // (relative to the location of gitignore). We achieve this by
@@ -314,7 +304,6 @@ impl GitignoreBuilder {
opts.require_literal_separator = true; opts.require_literal_separator = true;
line = &line[1..]; line = &line[1..];
} }
_ => {}
} }
// If it ends with a slash, then this should only match directories, // If it ends with a slash, then this should only match directories,
// but the slash should otherwise not be used while globbing. // but the slash should otherwise not be used while globbing.

View File

@@ -663,6 +663,18 @@ clean!(regression_65, "xyz", ".", |wd: WorkDir, mut cmd: Command| {
wd.assert_err(&mut cmd); wd.assert_err(&mut cmd);
}); });
// See: https://github.com/BurntSushi/ripgrep/issues/67
clean!(regression_67, "test", ".", |wd: WorkDir, mut cmd: Command| {
wd.create(".gitignore", "/*\n!/dir");
wd.create_dir("dir");
wd.create_dir("foo");
wd.create("foo/bar", "test");
wd.create("dir/bar", "test");
let lines: String = wd.stdout(&mut cmd);
assert_eq!(lines, "dir/bar:test\n");
});
// See: https://github.com/BurntSushi/ripgrep/issues/20 // See: https://github.com/BurntSushi/ripgrep/issues/20
sherlock!(feature_20, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| { sherlock!(feature_20, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
cmd.arg("--no-filename"); cmd.arg("--no-filename");