{ 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;
for (line = buf; *line; line = strchrnul(line+1, '\n')) {
while (*line == '\n')
line++;
+ if (!*line)
+ break;
+
/* Skip lines that don't start with GNUPG status */
if (!skip_prefix(line, "[GNUPG:] ", &line))
continue;
/* 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;