From: Junio C Hamano Date: Wed, 3 May 2006 00:27:07 +0000 (-0700) Subject: builtin-grep: tighten path wildcard vs tree traversal. X-Git-Tag: v1.4.0-rc1~142^2~12 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=1e3d90e0135274ad89cd8ee0722e2dd043ec0052;p=git.git builtin-grep: tighten path wildcard vs tree traversal. The earlier code descended into Documentation/technical when given "Documentation/how*" as the pattern, which was too loose. Signed-off-by: Junio C Hamano --- diff --git a/builtin-grep.c b/builtin-grep.c index 09e367782..2124fa62e 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -26,7 +26,7 @@ static int pathspec_matches(const char **paths, const char *name) for (i = 0; paths[i]; i++) { const char *match = paths[i]; int matchlen = strlen(match); - const char *slash, *cp; + const char *cp, *meta; if ((matchlen <= namelen) && !strncmp(name, match, matchlen) && @@ -38,38 +38,43 @@ static int pathspec_matches(const char **paths, const char *name) if (name[namelen-1] != '/') continue; - /* We are being asked if the name directory is worth + /* We are being asked if the directory ("name") is worth * descending into. * * Find the longest leading directory name that does * not have metacharacter in the pathspec; the name * 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; - if (ch == '/') - slash = cp; - if (ch == '*' || ch == '[') + if (ch == '*' || ch == '[' || ch == '?') { + meta = cp; break; + } } - if (!slash) - slash = match; /* toplevel */ - else - slash++; - if (namelen <= slash - match) { + if (!meta) + meta = cp; /* fully literal */ + + if (namelen <= meta - match) { /* Looking at "Documentation/" and * the pattern says "Documentation/howto/", or - * "Documentation/diff*.txt". + * "Documentation/diff*.txt". The name we + * have should match prefix. */ if (!memcmp(match, name, namelen)) return 1; + continue; } - else { + + if (meta - match < namelen) { /* 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; + continue; } } return 0;