diff --git a/src/commit.c b/src/commit.c index 79f287eea..9449224ef 100644 --- a/src/commit.c +++ b/src/commit.c @@ -135,7 +135,6 @@ int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) { const char *buffer = data; const char *buffer_end = (const char *)data + len; - git_oid parent_id; git_vector_init(&commit->parent_ids, 4, NULL); @@ -148,9 +147,7 @@ int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) */ while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) { - git_oid *new_id; - - new_id = git__malloc(sizeof(git_oid)); + git_oid *new_id = git__malloc(sizeof(git_oid)); GITERR_CHECK_ALLOC(new_id); git_oid_cpy(new_id, &parent_id); @@ -172,24 +169,29 @@ int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0) return -1; - if (git__prefixcmp(buffer, "encoding ") == 0) { - const char *encoding_end; - buffer += strlen("encoding "); + /* Parse add'l header entries until blank line found */ + while (buffer < buffer_end && *buffer != '\n') { + const char *eoln = buffer; + while (eoln < buffer_end && *eoln != '\n') + ++eoln; + if (eoln < buffer_end && *eoln == '\n') + ++eoln; - encoding_end = buffer; - while (encoding_end < buffer_end && *encoding_end != '\n') - encoding_end++; + if (git__prefixcmp(buffer, "encoding ") == 0) { + buffer += strlen("encoding "); - commit->message_encoding = git__strndup(buffer, encoding_end - buffer); - GITERR_CHECK_ALLOC(commit->message_encoding); + commit->message_encoding = git__strndup(buffer, eoln - buffer); + GITERR_CHECK_ALLOC(commit->message_encoding); + } - buffer = encoding_end; + buffer = eoln; } - /* parse commit message */ + /* skip blank lines */ while (buffer < buffer_end - 1 && *buffer == '\n') buffer++; + /* parse commit message */ if (buffer <= buffer_end) { commit->message = git__strndup(buffer, buffer_end - buffer); GITERR_CHECK_ALLOC(commit->message); diff --git a/tests-clar/commit/parse.c b/tests-clar/commit/parse.c index 8075f2619..908d9fba8 100644 --- a/tests-clar/commit/parse.c +++ b/tests-clar/commit/parse.c @@ -236,6 +236,30 @@ author Vicent Marti 1273848544 +0200\n\ committer Vicent Marti 1273848544 +0200\n\ \n\ a simple commit which works\n", +/* simple commit with GPG signature */ +"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\ +parent 34734e478d6cf50c27c9d69026d93974d052c454\n\ +author Ben Burkert 1358451456 -0800\n\ +committer Ben Burkert 1358451456 -0800\n\ +gpgsig -----BEGIN PGP SIGNATURE-----\n\ + Version: GnuPG v1.4.12 (Darwin)\n\ + \n\ + iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al\n\ + o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8\n\ + JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq\n\ + AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq\n\ + SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW\n\ + who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok\n\ + 6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG\n\ + cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu\n\ + c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9\n\ + ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J\n\ + 7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc\n\ + cpxtDQQMGYFpXK/71stq\n\ + =ozeK\n\ + -----END PGP SIGNATURE-----\n\ +\n\ +a simple commit which works\n", }; void test_commit_parse__entire_commit(void) @@ -251,10 +275,8 @@ void test_commit_parse__entire_commit(void) commit->object.repo = g_repo; cl_git_fail(git_commit__parse_buffer( - commit, - failing_commit_cases[i], - strlen(failing_commit_cases[i])) - ); + commit, failing_commit_cases[i], strlen(failing_commit_cases[i])) + ); git_commit__free(commit); } @@ -272,17 +294,11 @@ void test_commit_parse__entire_commit(void) strlen(passing_commit_cases[i])) ); - git_commit__free(commit); - - commit = (git_commit*)git__malloc(sizeof(git_commit)); - memset(commit, 0x0, sizeof(git_commit)); - commit->object.repo = g_repo; - - cl_git_pass(git_commit__parse_buffer( - commit, - passing_commit_cases[i], - strlen(passing_commit_cases[i])) - ); + if (!i) + cl_assert_equal_s("\n", git_commit_message(commit)); + else + cl_assert(git__prefixcmp( + git_commit_message(commit), "a simple commit which works") == 0); git_commit__free(commit); }