This patch is based on Eike Rathke's patches, which I plan to push soon.

Going a step further towards cleaning up and optimizing the matching,
this patch pulls the key matching out of the address match loop.

To keep the logic consistent, it explicitly checks for an empty address
list and skips those keys.  That shouldn't happen, but those keys aren't
usable inside pgp_select_key() in any case, and we don't want to prompt
to select a key from an empty list.

-Kevin
# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1421711918 28800
#      Mon Jan 19 15:58:38 2015 -0800
# Node ID cce9c9188b6961e7db4531d75ae01ab22bec4be7
# Parent  92ced228e98e8e3f5a2c4f942522eb5f2a46ad2b
pgp_getkeybystr: Pull key matching out of the address match loop.

Since the key is invariant inside the address loop, there is no need to
match against it with each address.

All the keys should have at least one address record (see bb3b01f41ed2),
but in case a record was malformed, add a check for that to keep the
same logic.

diff --git a/pgpkey.c b/pgpkey.c
--- a/pgpkey.c
+++ b/pgpkey.c
@@ -950,40 +950,55 @@
    * pgp_key_t->keyid should always contain a long key ID without 0x.
    * Strip leading "0x" before loops so it doesn't have to be done over and
    * over again, and prepare pl and ps to simplify logic in the loop's inner
    * condition.
    */
   pl = (!mutt_strncasecmp (p, "0x", 2) ? p + 2 : p);
   ps = (mutt_strlen (pl) == 16 ? pl + 8 : pl);
 
-  /* If ps != pl it means a long ID (or name of 16 characters) was given, do
-   * not attempt to match short IDs then. Also, it is unnecessary to try to
-   * match pl against long IDs if ps == pl as pl could not be a long ID. */
-
   for (k = keys; k; k = kn)
   {
     kn = k->next;
     if (abilities && !(k->flags & abilities))
       continue;
 
+    /* This shouldn't happen, but keys without any addresses aren't selectable
+     * in pgp_select_key().
+     */
+    if (!k->address)
+      continue;
+
     match = 0;
 
-    for (a = k->address; a; a = a->next)
+    dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key 
%s:\n",
+                p, pgp_long_keyid (k)));
+
+    /* If ps != pl it means a long ID (or name of 16 characters) was given, do
+     * not attempt to match short IDs then. Also, it is unnecessary to try to
+     * match pl against long IDs if ps == pl as pl could not be a long ID. */
+    if (!*p ||
+        (ps != pl && mutt_strcasecmp (pl, pgp_long_keyid (k)) == 0) ||
+        (ps == pl && mutt_strcasecmp (ps, pgp_short_keyid (k)) == 0))
     {
-      dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key %s, 
\"%s\": ",
-                  p, pgp_long_keyid (k), NONULL (a->addr)));
-      if (!*p ||
-          (ps != pl && mutt_strcasecmp (pl, pgp_long_keyid (k)) == 0) ||
-          (ps == pl && mutt_strcasecmp (ps, pgp_short_keyid (k)) == 0) ||
-         mutt_stristr (a->addr, p))
+      dprint (5, (debugfile, "\t\tmatch.\n"));
+      match = 1;
+    }
+    else
+    {
+      for (a = k->address; a; a = a->next)
       {
-       dprint (5, (debugfile, "match.\n"));
-       match = 1;
-       break;
+        dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key 
%s, \"%s\":\n",
+                    p, pgp_long_keyid (k), NONULL (a->addr)));
+        if (mutt_stristr (a->addr, p))
+        {
+          dprint (5, (debugfile, "\t\tmatch.\n"));
+          match = 1;
+          break;
+        }
       }
     }
 
     if (match)
     {
       *last = pgp_principal_key (k);
       kn    = pgp_remove_key (&keys, *last);
       last  = pgp_get_lastp (k);

Attachment: signature.asc
Description: PGP signature

Reply via email to