Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- cache.h | 17 +++++++++++++++++ dir.c | 18 +++++++++++------- tree-walk.c | 30 +++++++++++++++++++----------- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/cache.h b/cache.h index c3b5585..216f87c 100644 --- a/cache.h +++ b/cache.h @@ -522,6 +522,23 @@ extern void free_pathspec(struct pathspec *); extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); extern int limit_pathspec_to_literal(void); +static inline int ps_strncmp(const struct pathspec_item *item, + const char *s1, const char *s2, size_t n) +{ + if (item->magic & PATHSPEC_ICASE) + return strncasecmp(s1, s2, n); + else + return strncmp(s1, s2, n); +} + +static inline int ps_strcmp(const struct pathspec_item *item, + const char *s1, const char *s2) +{ + if (item->magic & PATHSPEC_ICASE) + return strcasecmp(s1, s2); + else + return strcmp(s1, s2); +} #define HASH_WRITE_OBJECT 1 #define HASH_FORMAT_CHECK 2 diff --git a/dir.c b/dir.c index d0e7ca8..e9edb65 100644 --- a/dir.c +++ b/dir.c @@ -42,7 +42,7 @@ inline int git_fnmatch(const struct pathspec_item *item, int prefix) { if (prefix > 0) { - if (strncmp(pattern, string, prefix)) + if (ps_strncmp(item, pattern, string, prefix)) return FNM_NOMATCH; pattern += prefix; string += prefix; @@ -51,14 +51,16 @@ inline int git_fnmatch(const struct pathspec_item *item, int pattern_len = strlen(++pattern); int string_len = strlen(string); return string_len < pattern_len || - strcmp(pattern, - string + string_len - pattern_len); + ps_strcmp(item, pattern, + string + string_len - pattern_len); } if (item->magic & PATHSPEC_GLOB) - return wildmatch(pattern, string, 0); + return wildmatch(pattern, string, + item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0); else /* wildmatch has not learned no FNM_PATHNAME mode yet */ - return fnmatch(pattern, string, 0); + return fnmatch(pattern, string, + item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0); } static size_t common_prefix_len(const struct pathspec *pathspec) @@ -162,7 +164,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, if (!*match) return MATCHED_RECURSIVELY; - if (matchlen <= namelen && !strncmp(match, name, matchlen)) { + if (matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) { if (matchlen == namelen) return MATCHED_EXACTLY; @@ -192,10 +194,12 @@ int match_pathspec_depth(const struct pathspec *ps, { int i, retval = 0; + /* BUG: we should not match icase on the prefix part */ GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL | - PATHSPEC_GLOB); + PATHSPEC_GLOB | + PATHSPEC_ICASE); if (!ps->nr) { if (!ps->recursive || ps->max_depth == -1) diff --git a/tree-walk.c b/tree-walk.c index 1679ce7..3d9c2ba 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -488,7 +488,8 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch return retval; } -static int match_entry(const struct name_entry *entry, int pathlen, +static int match_entry(const struct pathspec_item *item, + const struct name_entry *entry, int pathlen, const char *match, int matchlen, enum interesting *never_interesting) { @@ -504,8 +505,8 @@ static int match_entry(const struct name_entry *entry, int pathlen, * Does match sort strictly earlier than path * with their common parts? */ - m = strncmp(match, entry->path, - (matchlen < pathlen) ? matchlen : pathlen); + m = ps_strncmp(item, match, entry->path, + (matchlen < pathlen) ? matchlen : pathlen); if (m < 0) return 0; @@ -540,7 +541,7 @@ static int match_entry(const struct name_entry *entry, int pathlen, * we cheated and did not do strncmp(), so we do * that here. */ - m = strncmp(match, entry->path, pathlen); + m = ps_strncmp(item, match, entry->path, pathlen); /* * If common part matched earlier then it is a hit, @@ -553,10 +554,11 @@ static int match_entry(const struct name_entry *entry, int pathlen, return 0; } -static int match_dir_prefix(const char *base, +static int match_dir_prefix(const struct pathspec_item *item, + const char *base, const char *match, int matchlen) { - if (strncmp(base, match, matchlen)) + if (ps_strncmp(item, base, match, matchlen)) return 0; /* @@ -593,7 +595,7 @@ static int match_wildcard_base(const struct pathspec_item *item, */ if (baselen >= matchlen) { *matched = matchlen; - return !strncmp(base, match, matchlen); + return !ps_strncmp(item, base, match, matchlen); } dirlen = matchlen; @@ -606,7 +608,7 @@ static int match_wildcard_base(const struct pathspec_item *item, * base ends with '/' so we are sure it really matches * directory */ - if (strncmp(base, match, baselen)) + if (ps_strncmp(item, base, match, baselen)) return 0; *matched = baselen; } else @@ -635,10 +637,16 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, enum interesting never_interesting = ps->has_wildcard ? entry_not_interesting : all_entries_not_interesting; + /* + * BUG: we should not match icase on the prefix part. The + * prefix length is in 'ps'. Although using it won't be easy + * as the pattern is cut into pieces... + */ GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL | - PATHSPEC_GLOB); + PATHSPEC_GLOB | + PATHSPEC_ICASE); if (!ps->nr) { if (!ps->recursive || ps->max_depth == -1) @@ -659,7 +667,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, if (baselen >= matchlen) { /* If it doesn't match, move along... */ - if (!match_dir_prefix(base_str, match, matchlen)) + if (!match_dir_prefix(item, base_str, match, matchlen)) goto match_wildcards; if (!ps->recursive || ps->max_depth == -1) @@ -674,7 +682,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, /* Either there must be no base, or the base must match. */ if (baselen == 0 || !strncmp(base_str, match, baselen)) { - if (match_entry(entry, pathlen, + if (match_entry(item, entry, pathlen, match + baselen, matchlen - baselen, &never_interesting)) return entry_interesting; -- 1.8.0.rc2.23.g1fb49df -- 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