mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
gpg: Fix cache consistency problem.
g10/keyring.c (keyring_search): Only mark the cache as completely filled if we start the scan from the beginning of the keyring. -- Signed-off-by: Neal H. Walfield <neal@g10code.com> Reported-by: NIIBE Yutaka <gniibe@fsij.org> A new feature (e8c53fc) turned up a bug whereby checking if a search term matches multiple keys in the keyring causes the cache to be inconsistent. When we look for a key on the keyring, we iterate over each of the keyblocks starting with the keyblock following the last result. For each keyblock, we iterate over the public key and any subkeys. As we iterate over each key, we first insert it into the cache and then check if the key matches. If so, we are done. In pseudo code: for (i = last_result + 1; i < num_records; i ++) keyblock = get_keyblock (i) for (j = 1; j < len(keyblock); j ++) key = keyblock[j] update_cache (key) if (compare (key, search_terms)) return ok cache_filled = true return ENOFOUND When we look for the next match, we start with the following keyblock. The result is that any subkeys following the key that matched are not added to the cache (in other words, when a keyblock matches, the inner loop did not necessarily complete and the subsequent search doesn't resume it). This patch includes a straightforward fix: only indicate the cache as complete if we started the scan from the beginning of the keyring and really didn't find anything.
This commit is contained in:
parent
67c701d1e5
commit
7546e81879
@ -943,6 +943,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
int need_uid, need_words, need_keyid, need_fpr, any_skip;
|
||||
int pk_no, uid_no;
|
||||
int initial_skip;
|
||||
int scanned_from_start;
|
||||
int use_offtbl;
|
||||
PKT_user_id *uid = NULL;
|
||||
PKT_public_key *pk = NULL;
|
||||
@ -1045,6 +1046,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
main_offset = 0;
|
||||
pk_no = uid_no = 0;
|
||||
initial_skip = 1; /* skip until we see the start of a keyblock */
|
||||
scanned_from_start = iobuf_tell (hd->current.iobuf) == 0;
|
||||
while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid)))
|
||||
{
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
@ -1080,7 +1082,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
if (need_keyid)
|
||||
keyid_from_pk (pk, aki);
|
||||
|
||||
if (use_offtbl && !kr_offtbl_ready)
|
||||
if (use_offtbl && !kr_offtbl_ready && scanned_from_start)
|
||||
update_offset_hash_table (kr_offtbl, aki, main_offset);
|
||||
}
|
||||
else if (pkt.pkttype == PKT_USER_ID)
|
||||
@ -1168,7 +1170,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
hd->current.eof = 1;
|
||||
/* if we scanned all keyrings, we are sure that
|
||||
* all known key IDs are in our offtbl, mark that. */
|
||||
if (use_offtbl && !kr_offtbl_ready)
|
||||
if (use_offtbl && !kr_offtbl_ready && scanned_from_start)
|
||||
{
|
||||
KR_NAME kr;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user