summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2019-09-17 16:34:55 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-09-17 19:20:35 (GMT)
commita5e916c7453bc022cb86d7f8528952ccda6a81ce (patch)
tree4927aa8477860cbc1a6752cc3672895dcf75b072 /dir.c
parentbbbb6b0b898d0a03175a902524fb3a371fbd5b3f (diff)
downloadgit-a5e916c7453bc022cb86d7f8528952ccda6a81ce.zip
git-a5e916c7453bc022cb86d7f8528952ccda6a81ce.tar.gz
git-a5e916c7453bc022cb86d7f8528952ccda6a81ce.tar.bz2
dir: fix off-by-one error in match_pathspec_item
For a pathspec like 'foo/bar' comparing against a path named "foo/", namelen will be 4, and match[namelen] will be 'b'. The correct location of the directory separator is namelen-1. However, other callers of match_pathspec_item() such as builtin/grep.c's submodule_path_match() will compare against a path named "foo" instead of "foo/". It might be better to change all the callers to be consistent, as discussed at https://public-inbox.org/git/xmqq7e6cdnkr.fsf@gitster-ct.c.googlers.com/ and https://public-inbox.org/git/CABPp-BERWUPCPq-9fVW1LNocqkrfsoF4BPj3gJd9+En43vEkTQ@mail.gmail.com/ but there are many cases to audit, so for now just make sure we handle both cases with and without a trailing slash. The reason the code worked despite this sometimes-off-by-one error was that the subsequent code immediately checked whether the first matchlen characters matched (which they do) and then bailed and return MATCHED_RECURSIVELY anyway since wildmatch doesn't have the ability to check if "name" can be matched as a directory (or prefix) against the pathspec. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/dir.c b/dir.c
index a9168be..bf1a747 100644
--- a/dir.c
+++ b/dir.c
@@ -356,8 +356,9 @@ static int match_pathspec_item(const struct index_state *istate,
/* Perform checks to see if "name" is a super set of the pathspec */
if (flags & DO_MATCH_SUBMODULE) {
/* name is a literal prefix of the pathspec */
+ int offset = name[namelen-1] == '/' ? 1 : 0;
if ((namelen < matchlen) &&
- (match[namelen] == '/') &&
+ (match[namelen-offset] == '/') &&
!ps_strncmp(item, match, name, namelen))
return MATCHED_RECURSIVELY;