[PATCH 3/4] attr.c::path_matches(): special case paths that end with a slash
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:56:31
Subsystem:
the rest · Maintainer:
Linus Torvalds
The function is given a string that ends with a slash to signal that the path is a directory to make sure that a pattern that ends with a slash (i.e. MUSTBEDIR) can tell directories and non-directories apart. However, the pattern itself (pat->pattern and pat->patternlen) that came from such a MUSTBEDIR pattern is represented as a string that ends with a slash, but patternlen does not count that trailing slash. A MUSTBEDIR pattern "element/" is represented as a counted string <"element/", 7> and this must match match pathname "element/". Because match_basename() wants to see pathname "element" to match against the pattern <"element/", 7>, reduce the length of the path to exclude the trailing slash when calling match_basename(). A similar adjustment for match_pathname() might be needed, but I didn't look into it. Signed-off-by: Junio C Hamano <redacted> --- attr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/attr.c b/attr.c
index 4cfe0ee..00a0016 100644
--- a/attr.c
+++ b/attr.c@@ -661,14 +661,14 @@ static int path_matches(const char *pathname, int pathlen, { const char *pattern = pat->pattern; int prefix = pat->nowildcardlen; + int isdir = (pathlen && pathname[pathlen - 1] == '/'); - if ((pat->flags & EXC_FLAG_MUSTBEDIR) && - ((!pathlen) || (pathname[pathlen-1] != '/'))) + if ((pat->flags & EXC_FLAG_MUSTBEDIR) && !isdir) return 0; if (pat->flags & EXC_FLAG_NODIR) { return match_basename(pathname + basename_offset, - pathlen - basename_offset, + pathlen - basename_offset - isdir, pattern, prefix, pat->patternlen, pat->flags); }
--
1.8.2-350-g3df87a1