From 4974e3a59648095ffa6fce6c5b651a820c0c34b9 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Oct 2016 09:18:55 +0200 Subject: [PATCH 1/2] tree: validate filename and OID length when parsing object When parsing tree entries from raw object data, we do not verify that the tree entry actually has a filename as well as a valid object ID. Fix this by asserting that the filename length is non-zero as well as asserting that there are at least `GIT_OID_RAWSZ` bytes left when parsing the OID. --- src/tree.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tree.c b/src/tree.c index 5db2446bf..6008a9544 100644 --- a/src/tree.c +++ b/src/tree.c @@ -447,7 +447,12 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj) if ((nul = memchr(buffer, 0, buffer_end - buffer)) == NULL) return tree_error("Failed to parse tree. Object is corrupted", NULL); - filename_len = nul - buffer; + if ((filename_len = nul - buffer) == 0) + return tree_error("Failed to parse tree. Can't parse filename", NULL); + + if ((buffer_end - (nul + 1)) < GIT_OID_RAWSZ) + return tree_error("Failed to parse tree. Can't parse OID", NULL); + /* Allocate the entry */ { entry = git_array_alloc(tree->entries); From a719ef5e6d4a1a8ec53469c7914032ed67922772 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Oct 2016 09:31:41 +0200 Subject: [PATCH 2/2] commit: always initialize commit message When parsing a commit, we will treat all bytes left after parsing the headers as the commit message. When no bytes are left, we leave the commit's message uninitialized. While uncommon to have a commit without message, this is the right behavior as Git unfortunately allows for empty commit messages. Given that this scenario is so uncommon, most programs acting on the commit message will never check if the message is actually set, which may lead to errors. To work around the error and not lay the burden of checking for empty commit messages to the developer, initialize the commit message with an empty string when no commit message is given. --- src/commit.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/commit.c b/src/commit.c index 99a80855c..76e6dcbc9 100644 --- a/src/commit.c +++ b/src/commit.c @@ -459,10 +459,11 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) buffer = buffer_start + header_len + 1; /* extract commit message */ - if (buffer <= buffer_end) { + if (buffer <= buffer_end) commit->raw_message = git__strndup(buffer, buffer_end - buffer); - GITERR_CHECK_ALLOC(commit->raw_message); - } + else + commit->raw_message = git__strdup(""); + GITERR_CHECK_ALLOC(commit->raw_message); return 0;