changeset: 6398:58a9dbfd0d25
user: Kevin McCarthy <[email protected]>
date: Sat Jan 17 14:34:13 2015 -0800
link: http://dev.mutt.org/hg/mutt/rev/58a9dbfd0d25
Fix some context, data, and key memory leaks in gpgme.
The context and data cleanup just involved adding missing
gpgme_release() and gpgme_data_release() calls in a few places.
The key usage was a little more involved:
* Fix crypt_free_key(). It wasn't freeing the key passed in, and
didn't work properly if multiple keys were passed in. It also was
missing a call to gpgme_key_unref().
* Add free_recipient_set() to properly unref all the keys before
freeing the array.
* Fix get_candidates() to ref keys added to the crypt_key_t list, and
unref the keys returned by gpgme_op_keylist_next().
* Change usages of gpgme_key_release() to gpgme_key_unref(). The former
was deprecated in gpgme version 0.4.1 (2003-06-06).
diffs (247 lines):
diff -r cc7903944687 -r 58a9dbfd0d25 crypt-gpgme.c
--- a/crypt-gpgme.c Sat Jan 17 14:42:28 2015 -0800
+++ b/crypt-gpgme.c Sat Jan 17 14:34:13 2015 -0800
@@ -248,12 +248,19 @@
to NULL. */
static void crypt_free_key (crypt_key_t **keylist)
{
+ crypt_key_t *k;
+
+ if (!keylist)
+ return;
+
while (*keylist)
- {
- crypt_key_t *k = (*keylist)->next;
- FREE (&k);
- *keylist = k;
- }
+ {
+ k = *keylist;
+ *keylist = (*keylist)->next;
+
+ gpgme_key_unref (k->kobj);
+ FREE (&k);
+ }
}
/* Return trute when key K is valid. */
@@ -556,6 +563,28 @@
}
+static void free_recipient_set (gpgme_key_t **p_rset)
+{
+ gpgme_key_t *rset, k;
+
+ if (!p_rset)
+ return;
+
+ rset = *p_rset;
+ if (!rset)
+ return;
+
+ while (*rset)
+ {
+ k = *rset;
+ gpgme_key_unref (k);
+ rset++;
+ }
+
+ FREE (p_rset); /* __FREE_CHECKED__ */
+}
+
+
/* Create a GpgmeRecipientSet from the keys in the string KEYLIST.
The keys must be space delimited. */
static gpgme_key_t *create_recipient_set (const char *keylist,
@@ -608,7 +637,9 @@
{
mutt_error (_("error adding recipient `%s': %s\n"),
buf, gpgme_strerror (err));
- FREE (&rset);
+ rset[rset_n] = NULL;
+ free_recipient_set (&rset);
+ gpgme_release (context);
return NULL;
}
}
@@ -651,8 +682,8 @@
err = gpgme_op_keylist_next (listctx, &key2);
if (!err)
{
- gpgme_key_release (key);
- gpgme_key_release (key2);
+ gpgme_key_unref (key);
+ gpgme_key_unref (key2);
gpgme_release (listctx);
mutt_error (_("ambiguous specification of secret key `%s'\n"),
signid);
@@ -663,7 +694,7 @@
gpgme_signers_clear (ctx);
err = gpgme_signers_add (ctx, key);
- gpgme_key_release (key);
+ gpgme_key_unref (key);
if (err)
{
mutt_error (_("error setting secret key `%s': %s\n"),
@@ -834,6 +865,7 @@
if (set_signer (ctx, use_smime))
{
gpgme_data_release (signature);
+ gpgme_data_release (message);
gpgme_release (ctx);
return NULL;
}
@@ -962,13 +994,13 @@
plaintext = body_to_data_object (a, 0);
if (!plaintext)
{
- FREE (&rset);
+ free_recipient_set (&rset);
return NULL;
}
outfile = encrypt_gpgme_object (plaintext, rset, 0, sign);
gpgme_data_release (plaintext);
- FREE (&rset);
+ free_recipient_set (&rset);
if (!outfile)
return NULL;
@@ -1021,13 +1053,13 @@
plaintext = body_to_data_object (a, 0);
if (!plaintext)
{
- FREE (&rset);
+ free_recipient_set (&rset);
return NULL;
}
outfile = encrypt_gpgme_object (plaintext, rset, 1, 0);
gpgme_data_release (plaintext);
- FREE (&rset);
+ free_recipient_set (&rset);
if (!outfile)
return NULL;
@@ -1343,7 +1375,7 @@
if (signature_key)
{
- gpgme_key_release (signature_key);
+ gpgme_key_unref (signature_key);
signature_key = NULL;
}
@@ -1421,7 +1453,7 @@
}
if (key != signature_key)
- gpgme_key_release (key);
+ gpgme_key_unref (key);
}
return anybad ? 1 : anywarn ? 2 : 0;
@@ -1462,6 +1494,9 @@
state_attach_puts (_("[-- Begin signature information --]\n"), s);
err = gpgme_op_verify (ctx, signature, message, NULL);
+ gpgme_data_release (message);
+ gpgme_data_release (signature);
+
mutt_need_hard_redraw ();
if (err)
{
@@ -1479,7 +1514,7 @@
if (signature_key)
{
- gpgme_key_release (signature_key);
+ gpgme_key_unref (signature_key);
signature_key = NULL;
}
@@ -1967,7 +2002,7 @@
subkey = subkey->next;
more = 1;
}
- gpgme_key_release (key);
+ gpgme_key_unref (key);
}
if (gpg_err_code (err) != GPG_ERR_EOF)
{
@@ -2354,6 +2389,7 @@
FREE (&tmpfname);
}
}
+ gpgme_data_release (plaintext);
gpgme_release (ctx);
}
@@ -2405,6 +2441,7 @@
state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s);
}
+ gpgme_data_release (armored_data);
if (pgpout)
{
safe_fclose (&pgpout);
@@ -3515,7 +3552,7 @@
{
putc ('\n', fp);
err = gpgme_op_keylist_start (listctx, s, 0);
- gpgme_key_release (k);
+ gpgme_key_unref (k);
k = NULL;
if (!err)
err = gpgme_op_keylist_next (listctx, &k);
@@ -3538,7 +3575,7 @@
}
leave:
- gpgme_key_release (k);
+ gpgme_key_unref (k);
gpgme_release (listctx);
safe_fclose (&fp);
mutt_clear_error ();
@@ -3706,12 +3743,14 @@
{
k = safe_calloc (1, sizeof *k);
k->kobj = key;
+ gpgme_key_ref (k->kobj);
k->idx = idx;
k->uid = uid->uid;
k->flags = flags;
*kend = k;
kend = &k->next;
}
+ gpgme_key_unref (key);
}
if (gpg_err_code (err) != GPG_ERR_EOF)
mutt_error (_("gpgme_op_keylist_next failed: %s"), gpgme_strerror
(err));
@@ -3747,12 +3786,14 @@
{
k = safe_calloc (1, sizeof *k);
k->kobj = key;
+ gpgme_key_ref (k->kobj);
k->idx = idx;
k->uid = uid->uid;
k->flags = flags;
*kend = k;
kend = &k->next;
}
+ gpgme_key_unref (key);
}
if (gpg_err_code (err) != GPG_ERR_EOF)
mutt_error (_("gpgme_op_keylist_next failed: %s"), gpgme_strerror
(err));
@@ -4596,7 +4637,7 @@
if (signature_key)
{
- gpgme_key_release (signature_key);
+ gpgme_key_unref (signature_key);
signature_key = NULL;
}