Commit 251d8771 by Patrick Steinhardt

attr_file: fix handling of directory patterns with trailing spaces

When comparing whether a path matches a directory rule, we pass the
both the path and directory name to `fnmatch` with
`GIT_ATTR_FNMATCH_DIRECTORY` being set. `fnmatch` expects the pattern to
contain no trailing directory '/', which is why we try to always strip
patterns of trailing slashes. We do not handle that case correctly
though when the pattern itself has trailing spaces, causing the match to
fail.

Fix the issue by stripping trailing spaces and tabs for a rule previous
to checking whether the pattern is a directory pattern with a trailing
'/'. This replaces the whitespace-stripping in our ignore file parsing
code, which was stripping whitespaces too late. Add a test to catch
future breakage.
parent 0eca4230
......@@ -633,6 +633,11 @@ int git_attr_fnmatch__parse(
if (--spec->length == 0)
return GIT_ENOTFOUND;
/* Remove trailing spaces. */
while (pattern[spec->length - 1] == ' ' || pattern[spec->length - 1] == '\t')
if (--spec->length == 0)
return GIT_ENOTFOUND;
if (pattern[spec->length - 1] == '/') {
spec->length--;
spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY;
......
......@@ -213,16 +213,6 @@ static int parse_ignore_file(
if (ignore_case)
match->flags |= GIT_ATTR_FNMATCH_ICASE;
while (match->length > 0) {
if (match->pattern[match->length - 1] == ' ' ||
match->pattern[match->length - 1] == '\t') {
match->pattern[match->length - 1] = 0;
match->length --;
} else {
break;
}
}
scan = git__next_line(scan);
/*
......
......@@ -61,6 +61,22 @@ void test_attr_ignore__ignore_space(void)
assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
}
void test_attr_ignore__ignore_dir(void)
{
cl_git_rewritefile("attr/.gitignore", "dir/\n");
assert_is_ignored(true, "dir");
assert_is_ignored(true, "dir/file");
}
void test_attr_ignore__ignore_dir_with_trailing_space(void)
{
cl_git_rewritefile("attr/.gitignore", "dir/ \n");
assert_is_ignored(true, "dir");
assert_is_ignored(true, "dir/file");
}
void test_attr_ignore__ignore_root(void)
{
cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment