Skip to content

Commit 251d877

Browse files
committed
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.
1 parent 0eca423 commit 251d877

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

src/attr_file.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,11 @@ int git_attr_fnmatch__parse(
633633
if (--spec->length == 0)
634634
return GIT_ENOTFOUND;
635635

636+
/* Remove trailing spaces. */
637+
while (pattern[spec->length - 1] == ' ' || pattern[spec->length - 1] == '\t')
638+
if (--spec->length == 0)
639+
return GIT_ENOTFOUND;
640+
636641
if (pattern[spec->length - 1] == '/') {
637642
spec->length--;
638643
spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY;

src/ignore.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,6 @@ static int parse_ignore_file(
213213
if (ignore_case)
214214
match->flags |= GIT_ATTR_FNMATCH_ICASE;
215215

216-
while (match->length > 0) {
217-
if (match->pattern[match->length - 1] == ' ' ||
218-
match->pattern[match->length - 1] == '\t') {
219-
match->pattern[match->length - 1] = 0;
220-
match->length --;
221-
} else {
222-
break;
223-
}
224-
}
225-
226216
scan = git__next_line(scan);
227217

228218
/*

tests/attr/ignore.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,22 @@ void test_attr_ignore__ignore_space(void)
6161
assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
6262
}
6363

64+
void test_attr_ignore__ignore_dir(void)
65+
{
66+
cl_git_rewritefile("attr/.gitignore", "dir/\n");
67+
68+
assert_is_ignored(true, "dir");
69+
assert_is_ignored(true, "dir/file");
70+
}
71+
72+
void test_attr_ignore__ignore_dir_with_trailing_space(void)
73+
{
74+
cl_git_rewritefile("attr/.gitignore", "dir/ \n");
75+
76+
assert_is_ignored(true, "dir");
77+
assert_is_ignored(true, "dir/file");
78+
}
79+
6480
void test_attr_ignore__ignore_root(void)
6581
{
6682
cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");

0 commit comments

Comments
 (0)