The function takes two counted strings (<basename, basenamelen> and <pattern, patternlen>) as parameters, together with prefix (the length of the prefix in pattern that is to be matched literally without globbing against the basename) and EXC_* flags that tells it how to match the pattern against the basename. However, it did not pay attention to the length of these counted strings. Update them to do the following: * When the entire pattern is to be matched literally, the pattern matches the basename only when the lengths of them are the same, and they match up to that length. * When the pattern is "*" followed by a string to be matched literally, make sure that the basenamelen is equal or longer than the "literal" part of the pattern, and the tail of the basename string matches that literal part. * Otherwise, make sure we use only the counted part of the strings when calling fnmatch_icase(). Because these counted strings are full strings most of the time, avoid unnecessary allocation. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- dir.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/dir.c b/dir.c index 5a83aa7..aa16303 100644 --- a/dir.c +++ b/dir.c @@ -537,15 +537,38 @@ int match_basename(const char *basename, int basenamelen, int flags) { if (prefix == patternlen) { - if (!strcmp_icase(pattern, basename)) + if (patternlen == basenamelen && + !strncmp_icase(pattern, basename, basenamelen)) return 1; } else if (flags & EXC_FLAG_ENDSWITH) { + /* "*literal" matching against "fooliteral" */ if (patternlen - 1 <= basenamelen && - !strcmp_icase(pattern + 1, - basename + basenamelen - patternlen + 1)) + !strncmp_icase(pattern + 1, + basename + basenamelen - (patternlen - 1), + patternlen - 1)) return 1; } else { - if (fnmatch_icase(pattern, basename, 0) == 0) + int match_status; + struct strbuf pat = STRBUF_INIT; + struct strbuf base = STRBUF_INIT; + const char *use_pat = pattern; + const char *use_base = basename; + + if (pattern[patternlen]) { + strbuf_add(&pat, pattern, patternlen); + use_pat = pat.buf; + } + if (basename[basenamelen]) { + strbuf_add(&base, basename, basenamelen); + use_base = base.buf; + } + match_status = fnmatch_icase(use_pat, use_base, 0); + if (use_pat) + strbuf_release(&pat); + if (use_base) + strbuf_release(&base); + + if (match_status == 0) return 1; } return 0; -- 1.8.2-350-g3df87a1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html