Skip to content

Commit b0d6681

Browse files
committed
Merge branch 'hi/gpg-optional-pkfp-fix' into next
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
2 parents a4e4f06 + 67a6ea6 commit b0d6681

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

gpg-interface.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ static struct {
105105
{ 0, "VALIDSIG ", GPG_STATUS_FINGERPRINT },
106106
};
107107

108+
static void replace_cstring(char **field, const char *line, const char *next)
109+
{
110+
free(*field);
111+
112+
if (line && next)
113+
*field = xmemdupz(line, next - line);
114+
else
115+
*field = NULL;
116+
}
117+
108118
static void parse_gpg_output(struct signature_check *sigc)
109119
{
110120
const char *buf = sigc->gpg_status;
@@ -136,33 +146,43 @@ static void parse_gpg_output(struct signature_check *sigc)
136146
/* Do we have key information? */
137147
if (sigcheck_gpg_status[i].flags & GPG_STATUS_KEYID) {
138148
next = strchrnul(line, ' ');
139-
free(sigc->key);
140-
sigc->key = xmemdupz(line, next - line);
149+
replace_cstring(&sigc->key, line, next);
141150
/* Do we have signer information? */
142151
if (*next && (sigcheck_gpg_status[i].flags & GPG_STATUS_UID)) {
143152
line = next + 1;
144153
next = strchrnul(line, '\n');
145-
free(sigc->signer);
146-
sigc->signer = xmemdupz(line, next - line);
154+
replace_cstring(&sigc->signer, line, next);
147155
}
148156
}
149157
/* Do we have fingerprint? */
150158
if (sigcheck_gpg_status[i].flags & GPG_STATUS_FINGERPRINT) {
151-
next = strchrnul(line, ' ');
152-
free(sigc->fingerprint);
153-
sigc->fingerprint = xmemdupz(line, next - line);
159+
const char *limit;
160+
char **field;
154161

155-
/* Skip interim fields */
162+
next = strchrnul(line, ' ');
163+
replace_cstring(&sigc->fingerprint, line, next);
164+
165+
/*
166+
* Skip interim fields. The search is
167+
* limited to the same line since only
168+
* OpenPGP signatures has a field with
169+
* the primary fingerprint.
170+
*/
171+
limit = strchrnul(line, '\n');
156172
for (j = 9; j > 0; j--) {
157-
if (!*next)
173+
if (!*next || limit <= next)
158174
break;
159175
line = next + 1;
160176
next = strchrnul(line, ' ');
161177
}
162178

163-
next = strchrnul(line, '\n');
164-
free(sigc->primary_key_fingerprint);
165-
sigc->primary_key_fingerprint = xmemdupz(line, next - line);
179+
field = &sigc->primary_key_fingerprint;
180+
if (!j) {
181+
next = strchrnul(line, '\n');
182+
replace_cstring(field, line, next);
183+
} else {
184+
replace_cstring(field, NULL, NULL);
185+
}
166186
}
167187

168188
break;

t/t4202-log.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,14 @@ test_expect_success GPG 'setup signed branch' '
15701570
git commit -S -m signed_commit
15711571
'
15721572

1573+
test_expect_success GPG 'setup signed branch with subkey' '
1574+
test_when_finished "git reset --hard && git checkout master" &&
1575+
git checkout -b signed-subkey master &&
1576+
echo foo >foo &&
1577+
git add foo &&
1578+
git commit -SB7227189 -m signed_commit
1579+
'
1580+
15731581
test_expect_success GPGSM 'setup signed branch x509' '
15741582
test_when_finished "git reset --hard && git checkout master" &&
15751583
git checkout -b signed-x509 master &&
@@ -1580,6 +1588,18 @@ test_expect_success GPGSM 'setup signed branch x509' '
15801588
git commit -S -m signed_commit
15811589
'
15821590

1591+
test_expect_success GPGSM 'log x509 fingerprint' '
1592+
echo "F8BF62E0693D0694816377099909C779FA23FD65 | " >expect &&
1593+
git log -n1 --format="%GF | %GP" signed-x509 >actual &&
1594+
test_cmp expect actual
1595+
'
1596+
1597+
test_expect_success GPGSM 'log OpenPGP fingerprint' '
1598+
echo "D4BE22311AD3131E5EDA29A461092E85B7227189" > expect &&
1599+
git log -n1 --format="%GP" signed-subkey >actual &&
1600+
test_cmp expect actual
1601+
'
1602+
15831603
test_expect_success GPG 'log --graph --show-signature' '
15841604
git log --graph --show-signature -n1 signed >actual &&
15851605
grep "^| gpg: Signature made" actual &&

0 commit comments

Comments
 (0)