mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 12:13:18 +00:00
ignore: fix directory limits when searching for star-star
In order to match the star-star, we disable the flag that's looking for a single path element, but that leads to searching for the pattern in the middle of elements in the input string. Mark when we're handing a star-star so we jump over the elements in our attempt to match the part of the pattern that comes after the star-star. While here, tighten up the check so we don't allow invalid rules through.
This commit is contained in:
parent
0f36271646
commit
1c3018eb12
@ -69,7 +69,8 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
|
||||
if (recurs-- == 0)
|
||||
return FNM_NORES;
|
||||
|
||||
for (stringstart = string;;)
|
||||
for (stringstart = string;;) {
|
||||
bool match_slash = false;
|
||||
switch (c = *pattern++) {
|
||||
case EOS:
|
||||
if ((flags & FNM_LEADING_DIR) && *string == '/')
|
||||
@ -93,11 +94,17 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
|
||||
* It will be restored if/when we recurse below.
|
||||
*/
|
||||
if (c == '*') {
|
||||
c = *++pattern;
|
||||
/* star-star-slash is at the end, match by default */
|
||||
if (c == EOS)
|
||||
return 0;
|
||||
/* Double-star must be at end or between slashes */
|
||||
if (c != '/')
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
c = *++pattern;
|
||||
flags &= ~FNM_PATHNAME;
|
||||
while (c == '*')
|
||||
c = *++pattern;
|
||||
if (c == '/')
|
||||
c = *++pattern;
|
||||
match_slash = true;
|
||||
}
|
||||
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
@ -128,7 +135,17 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
|
||||
return e;
|
||||
if (test == '/' && (flags & FNM_PATHNAME))
|
||||
break;
|
||||
++string;
|
||||
|
||||
/* searching for star-star, so we jump over entire dirs */
|
||||
if (match_slash) {
|
||||
const char *slash;
|
||||
if (!(slash = strchr(string, '/')))
|
||||
break;
|
||||
|
||||
string = slash + 1;
|
||||
} else {
|
||||
++string;
|
||||
}
|
||||
}
|
||||
return (FNM_NOMATCH);
|
||||
case '[':
|
||||
@ -170,6 +187,7 @@ p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
|
||||
++string;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
@ -134,13 +134,25 @@ void test_attr_ignore__leading_stars(void)
|
||||
|
||||
void test_attr_ignore__globs_and_path_delimiters(void)
|
||||
{
|
||||
cl_git_rewritefile("attr/.gitignore", "foo/bar/**");
|
||||
assert_is_ignored(true, "foo/bar/baz");
|
||||
assert_is_ignored(true, "foo/bar/baz/quux");
|
||||
|
||||
cl_git_rewritefile("attr/.gitignore", "_*/");
|
||||
assert_is_ignored(true, "sub/_test/a/file");
|
||||
assert_is_ignored(false, "test_folder/file");
|
||||
assert_is_ignored(true, "_test/file");
|
||||
assert_is_ignored(true, "_test/a/file");
|
||||
|
||||
cl_git_rewritefile("attr/.gitignore", "**/_*/");
|
||||
assert_is_ignored(true, "sub/_test/a/file");
|
||||
assert_is_ignored(false, "test_folder/file");
|
||||
assert_is_ignored(true, "_test/file");
|
||||
assert_is_ignored(true, "_test/a/file");
|
||||
|
||||
cl_git_rewritefile("attr/.gitignore", "**/_*/foo/bar/*ux");
|
||||
|
||||
assert_is_ignored(true, "sub/_test/foo/bar/qux/file");
|
||||
assert_is_ignored(true, "_test/foo/bar/qux/file");
|
||||
assert_is_ignored(true, "_test/foo/bar/crux/file");
|
||||
assert_is_ignored(false, "_test/foo/bar/code/file");
|
||||
|
Loading…
Reference in New Issue
Block a user