gpgme_signature_t current_sig;
int did_prepare_new_sig;
+ int only_newsig_seen;
} *op_data_t;
prepare_new_sig (op_data_t opd)
{
gpgme_signature_t sig;
-
- sig = calloc (1, sizeof (*sig));
- if (!sig)
- return gpg_error_from_errno (errno);
- if (!opd->result.signatures)
- opd->result.signatures = sig;
- if (opd->current_sig)
- opd->current_sig->next = sig;
- opd->current_sig = sig;
+
+ if (opd->only_newsig_seen && opd->current_sig)
+ {
+ /* We have only seen the NEWSIG status and nothing else - we
+ better skip this signature therefore and reuse it for the
+ next possible signature. */
+ sig = opd->current_sig;
+ memset (sig, 0, sizeof *sig);
+ assert (opd->result.signatures == sig);
+ }
+ else
+ {
+ sig = calloc (1, sizeof (*sig));
+ if (!sig)
+ return gpg_error_from_errno (errno);
+ if (!opd->result.signatures)
+ opd->result.signatures = sig;
+ if (opd->current_sig)
+ opd->current_sig->next = sig;
+ opd->current_sig = sig;
+ }
opd->did_prepare_new_sig = 1;
+ opd->only_newsig_seen = 0;
return 0;
}
case GPGME_STATUS_NEWSIG:
if (sig)
calc_sig_summary (sig);
- return prepare_new_sig (opd);
+ err = prepare_new_sig (opd);
+ opd->only_newsig_seen = 1;
+ return err;
case GPGME_STATUS_GOODSIG:
case GPGME_STATUS_EXPSIG:
case GPGME_STATUS_ERRSIG:
if (sig && !opd->did_prepare_new_sig)
calc_sig_summary (sig);
+ opd->only_newsig_seen = 0;
return parse_new_sig (opd, code, args);
case GPGME_STATUS_VALIDSIG:
+ opd->only_newsig_seen = 0;
return sig ? parse_valid_sig (sig, args)
: gpg_error (GPG_ERR_INV_ENGINE);
case GPGME_STATUS_NODATA:
+ opd->only_newsig_seen = 0;
if (!sig)
return gpg_error (GPG_ERR_NO_DATA);
sig->status = gpg_error (GPG_ERR_NO_DATA);
break;
case GPGME_STATUS_UNEXPECTED:
+ opd->only_newsig_seen = 0;
if (!sig)
return gpg_error (GPG_ERR_GENERAL);
sig->status = gpg_error (GPG_ERR_NO_DATA);
case GPGME_STATUS_NOTATION_NAME:
case GPGME_STATUS_NOTATION_DATA:
case GPGME_STATUS_POLICY_URL:
+ opd->only_newsig_seen = 0;
return sig ? parse_notation (sig, code, args)
: gpg_error (GPG_ERR_INV_ENGINE);
case GPGME_STATUS_TRUST_MARGINAL:
case GPGME_STATUS_TRUST_FULLY:
case GPGME_STATUS_TRUST_ULTIMATE:
+ opd->only_newsig_seen = 0;
return sig ? parse_trust (sig, code, args)
: gpg_error (GPG_ERR_INV_ENGINE);
case GPGME_STATUS_ERROR:
+ opd->only_newsig_seen = 0;
/* The error status is informational, so we don't return an
error code if we are not ready to process this status. */
return sig ? parse_error (sig, args) : 0;
case GPGME_STATUS_EOF:
if (sig && !opd->did_prepare_new_sig)
calc_sig_summary (sig);
+ if (opd->only_newsig_seen && sig)
+ {
+ gpgme_signature_t sig2;
+ /* The last signature has no valid information - remove it
+ from the list. */
+ assert (!sig->next);
+ if (sig == opd->result.signatures)
+ opd->result.signatures = NULL;
+ else
+ {
+ for (sig2 = opd->result.signatures; sig2; sig2 = sig2->next)
+ if (sig2->next == sig)
+ {
+ sig2->next = NULL;
+ break;
+ }
+ }
+ /* Note that there is no need to release the members of SIG
+ because we won't be here if they have been set. */
+ free (sig);
+ opd->current_sig = NULL;
+ }
+ opd->only_newsig_seen = 0;
break;
default: