Add skipping of unknown commit headers This moves the check for the "encoding" header into a loop which is just scanning for non-required headers at the end of a commit header. That loop will skip unrecognized lines (including header continuation lines) until a terminating completely blank line is found, and only then does it move to reading the commit message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
diff --git a/src/commit.c b/src/commit.c
index 79f287e..9449224 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 8075f26..908d9fb 100644
--- a/tests-clar/commit/parse.c
+++ b/tests-clar/commit/parse.c
@@ -236,6 +236,30 @@ author Vicent Marti <tanoku@gmail.com> 1273848544 +0200\n\
committer Vicent Marti <tanoku@gmail.com> 1273848544 +0200\n\
\n\
a simple commit which works\n",
+/* simple commit with GPG signature */
+"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
+parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
+author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
+committer Ben Burkert <ben@benburkert.com> 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);
}