Merge branch 'jk/match-pathname-fix'

The wildmatch code had a corner case bug that mistakenly makes
"foo**/bar" match with "foobar", which has been corrected.

* jk/match-pathname-fix:
  match_pathname(): give fnmatch one char of prefix context
  match_pathname(): reorder prefix-match check
main
Junio C Hamano 2025-11-03 06:49:54 -08:00
commit 5236467090
2 changed files with 23 additions and 5 deletions

17
dir.c
View File

@ -1388,18 +1388,25 @@ int match_pathname(const char *pathname, int pathlen,


if (fspathncmp(pattern, name, prefix)) if (fspathncmp(pattern, name, prefix))
return 0; return 0;
pattern += prefix;
patternlen -= prefix;
name += prefix;
namelen -= prefix;


/* /*
* If the whole pattern did not have a wildcard, * If the whole pattern did not have a wildcard,
* then our prefix match is all we need; we * then our prefix match is all we need; we
* do not need to call fnmatch at all. * do not need to call fnmatch at all.
*/ */
if (!patternlen && !namelen) if (patternlen == prefix && namelen == prefix)
return 1; return 1;

/*
* Retain one character of the prefix to
* pass to fnmatch, which lets it distinguish
* the start of a directory component correctly.
*/
prefix--;
pattern += prefix;
patternlen -= prefix;
name += prefix;
namelen -= prefix;
} }


return fnmatch_icase_mem(pattern, patternlen, return fnmatch_icase_mem(pattern, patternlen,

View File

@ -847,6 +847,17 @@ test_expect_success 'directories and ** matches' '
test_cmp expect actual test_cmp expect actual
' '


test_expect_success '** not confused by matching leading prefix' '
cat >.gitignore <<-\EOF &&
foo**/bar
EOF
git check-ignore foobar foo/bar >actual &&
cat >expect <<-\EOF &&
foo/bar
EOF
test_cmp expect actual
'

############################################################################ ############################################################################
# #
# test whitespace handling # test whitespace handling