mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-30 11:15:04 +00:00
Merge pull request #3599 from libgit2/gpgsign
Introduce git_commit_extract_signature
This commit is contained in:
commit
488e2b8505
@ -263,6 +263,18 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit, const char *field);
|
GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit, const char *field);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the signature from a commit
|
||||||
|
*
|
||||||
|
* @param signature the signature block
|
||||||
|
* @param signed_data signed data; this is the commit contents minus the signature block
|
||||||
|
* @param repo the repository in which the commit exists
|
||||||
|
* @param commit_id the commit from which to extract the data
|
||||||
|
* @param field the name of the header field containing the signature
|
||||||
|
* block; pass `NULL` to extract the default 'gpgsig'
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_repository *repo, git_oid *commit_id, const char *field);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new commit in the repository from a list of `git_object` pointers
|
* Create new commit in the repository from a list of `git_object` pointers
|
||||||
*
|
*
|
||||||
|
86
src/commit.c
86
src/commit.c
@ -621,3 +621,89 @@ oom:
|
|||||||
giterr_set_oom();
|
giterr_set_oom();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_repository *repo, git_oid *commit_id, const char *field)
|
||||||
|
{
|
||||||
|
git_odb_object *obj;
|
||||||
|
git_odb *odb;
|
||||||
|
const char *buf;
|
||||||
|
const char *h, *eol;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
git_buf_sanitize(signature);
|
||||||
|
git_buf_sanitize(signed_data);
|
||||||
|
|
||||||
|
if (!field)
|
||||||
|
field = "gpgsig";
|
||||||
|
|
||||||
|
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if ((error = git_odb_read(&obj, odb, commit_id)) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
buf = git_odb_object_data(obj);
|
||||||
|
|
||||||
|
while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
|
||||||
|
h++;
|
||||||
|
if (git__prefixcmp(buf, field)) {
|
||||||
|
if (git_buf_put(signed_data, buf, h - buf) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buf = h;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = buf;
|
||||||
|
h += strlen(field);
|
||||||
|
eol = strchr(h, '\n');
|
||||||
|
if (h[0] != ' ') {
|
||||||
|
buf = h;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!eol)
|
||||||
|
goto malformed;
|
||||||
|
|
||||||
|
h++; /* skip the SP */
|
||||||
|
|
||||||
|
git_buf_put(signature, h, eol - h);
|
||||||
|
if (git_buf_oom(signature))
|
||||||
|
goto oom;
|
||||||
|
|
||||||
|
/* If the next line starts with SP, it's multi-line, we must continue */
|
||||||
|
while (eol[1] == ' ') {
|
||||||
|
git_buf_putc(signature, '\n');
|
||||||
|
h = eol + 2;
|
||||||
|
eol = strchr(h, '\n');
|
||||||
|
if (!eol)
|
||||||
|
goto malformed;
|
||||||
|
|
||||||
|
git_buf_put(signature, h, eol - h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (git_buf_oom(signature))
|
||||||
|
goto oom;
|
||||||
|
|
||||||
|
git_odb_object_free(obj);
|
||||||
|
return git_buf_puts(signed_data, eol+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
giterr_set(GITERR_INVALID, "this commit is not signed");
|
||||||
|
error = GIT_ENOTFOUND;
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
malformed:
|
||||||
|
giterr_set(GITERR_OBJECT, "malformed header");
|
||||||
|
error = -1;
|
||||||
|
goto cleanup;
|
||||||
|
oom:
|
||||||
|
giterr_set_oom();
|
||||||
|
error = -1;
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
git_odb_object_free(obj);
|
||||||
|
git_buf_clear(signature);
|
||||||
|
git_buf_clear(signed_data);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
@ -460,3 +460,52 @@ cpxtDQQMGYFpXK/71stq\n\
|
|||||||
git_buf_free(&buf);
|
git_buf_free(&buf);
|
||||||
git_commit__free(commit);
|
git_commit__free(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_commit_parse__extract_signature(void)
|
||||||
|
{
|
||||||
|
git_odb *odb;
|
||||||
|
git_oid commit_id;
|
||||||
|
git_buf signature = GIT_BUF_INIT, signed_data = GIT_BUF_INIT;
|
||||||
|
const char *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-----";
|
||||||
|
|
||||||
|
const char *data = "tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
|
||||||
|
parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
|
||||||
|
author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||||
|
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||||
|
\n\
|
||||||
|
a simple commit which works\n";
|
||||||
|
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_odb__weakptr(&odb, g_repo));
|
||||||
|
cl_git_pass(git_odb_write(&commit_id, odb, passing_commit_cases[4], strlen(passing_commit_cases[4]), GIT_OBJ_COMMIT));
|
||||||
|
|
||||||
|
cl_git_pass(git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, NULL));
|
||||||
|
cl_assert_equal_s(gpgsig, signature.ptr);
|
||||||
|
cl_assert_equal_s(data, signed_data.ptr);
|
||||||
|
|
||||||
|
git_buf_clear(&signature);
|
||||||
|
git_buf_clear(&signed_data);
|
||||||
|
|
||||||
|
cl_git_pass(git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, "gpgsig"));
|
||||||
|
cl_assert_equal_s(gpgsig, signature.ptr);
|
||||||
|
cl_assert_equal_s(data, signed_data.ptr);
|
||||||
|
|
||||||
|
git_buf_free(&signature);
|
||||||
|
git_buf_free(&signed_data);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user