Skip to content

Commit 8a2c174

Browse files
peffgitster
authored andcommitted
pathspec: handle non-terminated strings with :(attr)
The pathspec code always takes names to be matched as a name/namelen pair, but match_attrs() never looks at namelen, and just treats "name" like a NUL-terminated string, passing it to git_check_attr(). This usually works anyway. Every caller passes a NUL-terminated string, and in all but one the passed-in length is the same as the length of the string (the exception is dir_path_match(), which may pass a smaller length to drop a trailing slash). So we won't currently ever read random memory, and the one case I found actually happens to work correctly because the attr code can handle the trailing slash itself. But it's still worth addressing, as the function interface implies that the name does not have to be NUL-terminated, making this an accident waiting to happen. Since teaching git_check_attr() to take a ptr/len pair would be a big refactor, we'll just allocate a new string. We can do this only when necessary, which avoids paying the cost for most callers. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c27cc94 commit 8a2c174

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

dir.c

+7
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,15 @@ static int match_attrs(const struct index_state *istate,
281281
const struct pathspec_item *item)
282282
{
283283
int i;
284+
char *to_free = NULL;
285+
286+
if (name[namelen])
287+
name = to_free = xmemdupz(name, namelen);
284288

285289
git_check_attr(istate, name, item->attr_check);
290+
291+
free(to_free);
292+
286293
for (i = 0; i < item->attr_match_nr; i++) {
287294
const char *value;
288295
int matched;

0 commit comments

Comments
 (0)