@ -1036,20 +1036,18 @@ static int do_sign_commit(struct strbuf *buf, const char *keyid)
@@ -1036,20 +1036,18 @@ static int do_sign_commit(struct strbuf *buf, const char *keyid)
}
int parse_signed_commit(const struct commit *commit,
struct strbuf *payload, struct strbuf *signature)
struct strbuf *payload, struct strbuf *signature,
const struct git_hash_algo *algop)
{
unsigned long size;
const char *buffer = get_commit_buffer(commit, &size);
int in_signature, saw_signature = -1;
const char *line, *tail;
const char *gpg_sig_header = gpg_sig_headers[hash_algo_by_ptr(the_hash_algo)];
int gpg_sig_header_len = strlen(gpg_sig_header);
int in_signature = 0, saw_signature = 0, other_signature = 0;
const char *line, *tail, *p;
const char *gpg_sig_header = gpg_sig_headers[hash_algo_by_ptr(algop)];
line = buffer;
tail = buffer + size;
in_signature = 0;
saw_signature = 0;
while (line < tail) {
const char *sig = NULL;
const char *next = memchr(line, '\n', tail - line);
@ -1057,9 +1055,15 @@ int parse_signed_commit(const struct commit *commit,
@@ -1057,9 +1055,15 @@ int parse_signed_commit(const struct commit *commit,
next = next ? next + 1 : tail;
if (in_signature && line[0] == ' ')
sig = line + 1;
else if (starts_with(line, gpg_sig_header) &&
line[gpg_sig_header_len] == ' ')
sig = line + gpg_sig_header_len + 1;
else if (skip_prefix(line, gpg_sig_header, &p) &&
*p == ' ') {
sig = line + strlen(gpg_sig_header) + 1;
other_signature = 0;
}
else if (starts_with(line, "gpgsig"))
other_signature = 1;
else if (other_signature && line[0] != ' ')
other_signature = 0;
if (sig) {
strbuf_add(signature, sig, next - sig);
saw_signature = 1;
@ -1068,7 +1072,8 @@ int parse_signed_commit(const struct commit *commit,
@@ -1068,7 +1072,8 @@ int parse_signed_commit(const struct commit *commit,
if (*line == '\n')
/* dump the whole remainder of the buffer */
next = tail;
strbuf_add(payload, line, next - line);
if (!other_signature)
strbuf_add(payload, line, next - line);
in_signature = 0;
}
line = next;
@ -1082,23 +1087,29 @@ int remove_signature(struct strbuf *buf)
@@ -1082,23 +1087,29 @@ int remove_signature(struct strbuf *buf)
const char *line = buf->buf;
const char *tail = buf->buf + buf->len;
int in_signature = 0;
const char *sig_start = NULL;
const char *sig_end = NULL;
struct sigbuf {
const char *start;
const char *end;
} sigs[2], *sigp = &sigs[0];
int i;
const char *orig_buf = buf->buf;
memset(sigs, 0, sizeof(sigs));
while (line < tail) {
const char *next = memchr(line, '\n', tail - line);
next = next ? next + 1 : tail;
if (in_signature && line[0] == ' ')
sig_end = next;
sigp->end = next;
else if (starts_with(line, "gpgsig")) {
int i;
for (i = 1; i < GIT_HASH_NALGOS; i++) {
const char *p;
if (skip_prefix(line, gpg_sig_headers[i], &p) &&
*p == ' ') {
sig_start = line;
sig_end = next;
sigp->start = line;
sigp->end = next;
in_signature = 1;
}
}
@ -1106,15 +1117,18 @@ int remove_signature(struct strbuf *buf)
@@ -1106,15 +1117,18 @@ int remove_signature(struct strbuf *buf)
if (*line == '\n')
/* dump the whole remainder of the buffer */
next = tail;
if (in_signature && sigp - sigs != ARRAY_SIZE(sigs))
sigp++;
in_signature = 0;
}
line = next;
}
if (sig_start)
strbuf_remove(buf, sig_start - buf->buf, sig_end - sig_start);
for (i = ARRAY_SIZE(sigs) - 1; i >= 0; i--)
if (sigs[i].start)
strbuf_remove(buf, sigs[i].start - orig_buf, sigs[i].end - sigs[i].start);
return sig_start != NULL;
return sigs[0].start != NULL;
}
static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
@ -1165,7 +1179,7 @@ int check_commit_signature(const struct commit *commit, struct signature_check *
@@ -1165,7 +1179,7 @@ int check_commit_signature(const struct commit *commit, struct signature_check *
sigc->result = 'N';
if (parse_signed_commit(commit, &payload, &signature) <= 0)
if (parse_signed_commit(commit, &payload, &signature, the_hash_algo) <= 0)
goto out;
ret = check_signature(payload.buf, payload.len, signature.buf,
signature.len, sigc);