Merge branch 'hi/gpg-optional-pkfp-fix'

The code to parse GPG output used to assume incorrectly that the
finterprint for the primary key would always be present for a valid
signature, which has been corrected.

* hi/gpg-optional-pkfp-fix:
  gpg-interface: limit search for primary key fingerprint
  gpg-interface: refactor the free-and-xmemdupz pattern
This commit is contained in:
Junio C Hamano 2019-12-05 12:52:46 -08:00
commit f06dff7b7c
2 changed files with 52 additions and 12 deletions

View file

@ -105,6 +105,16 @@ static struct {
{ 0, "VALIDSIG ", GPG_STATUS_FINGERPRINT },
};
static void replace_cstring(char **field, const char *line, const char *next)
{
free(*field);
if (line && next)
*field = xmemdupz(line, next - line);
else
*field = NULL;
}
static void parse_gpg_output(struct signature_check *sigc)
{
const char *buf = sigc->gpg_status;
@ -136,33 +146,43 @@ static void parse_gpg_output(struct signature_check *sigc)
/* Do we have key information? */
if (sigcheck_gpg_status[i].flags & GPG_STATUS_KEYID) {
next = strchrnul(line, ' ');
free(sigc->key);
sigc->key = xmemdupz(line, next - line);
replace_cstring(&sigc->key, line, next);
/* Do we have signer information? */
if (*next && (sigcheck_gpg_status[i].flags & GPG_STATUS_UID)) {
line = next + 1;
next = strchrnul(line, '\n');
free(sigc->signer);
sigc->signer = xmemdupz(line, next - line);
replace_cstring(&sigc->signer, line, next);
}
}
/* Do we have fingerprint? */
if (sigcheck_gpg_status[i].flags & GPG_STATUS_FINGERPRINT) {
next = strchrnul(line, ' ');
free(sigc->fingerprint);
sigc->fingerprint = xmemdupz(line, next - line);
const char *limit;
char **field;
/* Skip interim fields */
next = strchrnul(line, ' ');
replace_cstring(&sigc->fingerprint, line, next);
/*
* Skip interim fields. The search is
* limited to the same line since only
* OpenPGP signatures has a field with
* the primary fingerprint.
*/
limit = strchrnul(line, '\n');
for (j = 9; j > 0; j--) {
if (!*next)
if (!*next || limit <= next)
break;
line = next + 1;
next = strchrnul(line, ' ');
}
next = strchrnul(line, '\n');
free(sigc->primary_key_fingerprint);
sigc->primary_key_fingerprint = xmemdupz(line, next - line);
field = &sigc->primary_key_fingerprint;
if (!j) {
next = strchrnul(line, '\n');
replace_cstring(field, line, next);
} else {
replace_cstring(field, NULL, NULL);
}
}
break;

View file

@ -1570,6 +1570,14 @@ test_expect_success GPG 'setup signed branch' '
git commit -S -m signed_commit
'
test_expect_success GPG 'setup signed branch with subkey' '
test_when_finished "git reset --hard && git checkout master" &&
git checkout -b signed-subkey master &&
echo foo >foo &&
git add foo &&
git commit -SB7227189 -m signed_commit
'
test_expect_success GPGSM 'setup signed branch x509' '
test_when_finished "git reset --hard && git checkout master" &&
git checkout -b signed-x509 master &&
@ -1580,6 +1588,18 @@ test_expect_success GPGSM 'setup signed branch x509' '
git commit -S -m signed_commit
'
test_expect_success GPGSM 'log x509 fingerprint' '
echo "F8BF62E0693D0694816377099909C779FA23FD65 | " >expect &&
git log -n1 --format="%GF | %GP" signed-x509 >actual &&
test_cmp expect actual
'
test_expect_success GPGSM 'log OpenPGP fingerprint' '
echo "D4BE22311AD3131E5EDA29A461092E85B7227189" > expect &&
git log -n1 --format="%GP" signed-subkey >actual &&
test_cmp expect actual
'
test_expect_success GPG 'log --graph --show-signature' '
git log --graph --show-signature -n1 signed >actual &&
grep "^| gpg: Signature made" actual &&