Merge branch 'jc/grep' into next
* jc/grep: builtin-grep: tighten path wildcard vs tree traversal.
This commit is contained in:
commit
e0d7d6402d
@ -26,7 +26,7 @@ static int pathspec_matches(const char **paths, const char *name)
|
|||||||
for (i = 0; paths[i]; i++) {
|
for (i = 0; paths[i]; i++) {
|
||||||
const char *match = paths[i];
|
const char *match = paths[i];
|
||||||
int matchlen = strlen(match);
|
int matchlen = strlen(match);
|
||||||
const char *slash, *cp;
|
const char *cp, *meta;
|
||||||
|
|
||||||
if ((matchlen <= namelen) &&
|
if ((matchlen <= namelen) &&
|
||||||
!strncmp(name, match, matchlen) &&
|
!strncmp(name, match, matchlen) &&
|
||||||
@ -38,38 +38,43 @@ static int pathspec_matches(const char **paths, const char *name)
|
|||||||
if (name[namelen-1] != '/')
|
if (name[namelen-1] != '/')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We are being asked if the name directory is worth
|
/* We are being asked if the directory ("name") is worth
|
||||||
* descending into.
|
* descending into.
|
||||||
*
|
*
|
||||||
* Find the longest leading directory name that does
|
* Find the longest leading directory name that does
|
||||||
* not have metacharacter in the pathspec; the name
|
* not have metacharacter in the pathspec; the name
|
||||||
* we are looking at must overlap with that directory.
|
* we are looking at must overlap with that directory.
|
||||||
*/
|
*/
|
||||||
for (cp = match, slash = NULL; cp - match < matchlen; cp++) {
|
for (cp = match, meta = NULL; cp - match < matchlen; cp++) {
|
||||||
char ch = *cp;
|
char ch = *cp;
|
||||||
if (ch == '/')
|
if (ch == '*' || ch == '[' || ch == '?') {
|
||||||
slash = cp;
|
meta = cp;
|
||||||
if (ch == '*' || ch == '[')
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!slash)
|
}
|
||||||
slash = match; /* toplevel */
|
if (!meta)
|
||||||
else
|
meta = cp; /* fully literal */
|
||||||
slash++;
|
|
||||||
if (namelen <= slash - match) {
|
if (namelen <= meta - match) {
|
||||||
/* Looking at "Documentation/" and
|
/* Looking at "Documentation/" and
|
||||||
* the pattern says "Documentation/howto/", or
|
* the pattern says "Documentation/howto/", or
|
||||||
* "Documentation/diff*.txt".
|
* "Documentation/diff*.txt". The name we
|
||||||
|
* have should match prefix.
|
||||||
*/
|
*/
|
||||||
if (!memcmp(match, name, namelen))
|
if (!memcmp(match, name, namelen))
|
||||||
return 1;
|
return 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if (meta - match < namelen) {
|
||||||
/* Looking at "Documentation/howto/" and
|
/* Looking at "Documentation/howto/" and
|
||||||
* the pattern says "Documentation/h*".
|
* the pattern says "Documentation/h*";
|
||||||
|
* match up to "Do.../h"; this avoids descending
|
||||||
|
* into "Documentation/technical/".
|
||||||
*/
|
*/
|
||||||
if (!memcmp(match, name, slash - match))
|
if (!memcmp(match, name, meta - match))
|
||||||
return 1;
|
return 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user