From dfc2c713433b3a932e4d8b648738e3b63086baec Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Oct 2016 09:18:55 +0200 Subject: [PATCH 1/3] 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 3874e45f4..7cc415a09 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 821042b673675546a265827ea184c6fa14e0623d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Oct 2016 09:31:41 +0200 Subject: [PATCH 2/3] 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 5ed9c474d..ade4e10b5 100644 --- a/src/commit.c +++ b/src/commit.c @@ -410,10 +410,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; From f061aa85d5feb32d7e07c3fd554391976cfb3c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 5 Oct 2016 20:17:06 +0200 Subject: [PATCH 3/3] travis: take the newer ssh-keygen format into account The Mac machines have updated their SSH version and so the ssh-keygen format has changed. Ask it for MD5, which is the one that is output as hex. --- script/cibuild.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/script/cibuild.sh b/script/cibuild.sh index 5707f01cb..6709b38f9 100755 --- a/script/cibuild.sh +++ b/script/cibuild.sh @@ -44,8 +44,13 @@ ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys ssh-keyscan -t rsa localhost >>~/.ssh/known_hosts -# Get the fingerprint for localhost and remove the colons so we can parse it as a hex number -export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F localhost -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':') +# Get the fingerprint for localhost and remove the colons so we can parse it as +# a hex number. The Mac version is newer so it has a different output format. +if [ "$TRAVIS_OS_NAME" = "osx" ]; then + export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -E md5 -F localhost -l | tail -n 1 | cut -d ' ' -f 3 | cut -d : -f2- | tr -d :) +else + export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F localhost -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':') +fi export GITTEST_REMOTE_URL="ssh://localhost/$HOME/_temp/test.git" export GITTEST_REMOTE_USER=$USER