diff mbox series

[3/3] pathspec: handle non-terminated strings with :(attr)

Message ID 20181102052322.GC19234@sigill.intra.peff.net (mailing list archive)
State New, archived
Headers show
Series mixed bag of -Wunused-parameter bugfixes | expand

Commit Message

Jeff King Nov. 2, 2018, 5:23 a.m. UTC
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 <peff@peff.net>
 dir.c | 7 +++++++
 1 file changed, 7 insertions(+)
diff mbox series


diff --git a/dir.c b/dir.c
index 47c2fca8dc..ab6477d777 100644
--- a/dir.c
+++ b/dir.c
@@ -281,8 +281,15 @@  static int match_attrs(const struct index_state *istate,
 		       const struct pathspec_item *item)
 	int i;
+	char *to_free = NULL;
+	if (name[namelen])
+		name = to_free = xmemdupz(name, namelen);
 	git_check_attr(istate, name, item->attr_check);
+	free(to_free);
 	for (i = 0; i < item->attr_match_nr; i++) {
 		const char *value;
 		int matched;