From: Kevin McCarthy Date: Tue, 23 May 2017 01:18:29 +0000 (-0700) Subject: Don't clean up idata when closing an open-append mailbox. X-Git-Tag: neomutt-20170526~2^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e011333e56c5c2b047d9b719be4ab426b10246a7;p=neomutt Don't clean up idata when closing an open-append mailbox. open-append borrows the idata just for the connection. The "mailbox specific" part of the idata may be being used by a normal open-mailbox. Don't free the idata "mailbox specific" part when closing an open-append mailbox. Thanks to Will Yardley for discovering the bug as part of testing the revised IMAP fetch_headers code (in the default branch). --- diff --git a/imap/imap.c b/imap/imap.c index de53a45aa..474c2c8ad 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -1386,6 +1386,14 @@ int imap_close_mailbox(struct Context *ctx) if (!idata) return 0; + /* imap_open_mailbox_append() borrows the struct ImapData temporarily, + * just for the connection, but does not set idata->ctx to the + * open-append ctx. + * + * So when these are equal, it means we are actually closing the + * mailbox and should clean up idata. Otherwise, we don't want to + * touch idata - it's still being used. + */ if (ctx == idata->ctx) { if (idata->status != IMAP_FATAL && idata->state >= IMAP_SELECTED) @@ -1401,6 +1409,19 @@ int imap_close_mailbox(struct Context *ctx) FREE(&(idata->mailbox)); mutt_free_list(&idata->flags); idata->ctx = NULL; + + hash_destroy(&idata->uid_hash, NULL); + + for (i = 0; i < IMAP_CACHE_LEN; i++) + { + if (idata->cache[i].path) + { + unlink(idata->cache[i].path); + FREE(&idata->cache[i].path); + } + } + + mutt_bcache_close(&idata->bcache); } /* free IMAP part of headers */ @@ -1408,20 +1429,6 @@ int imap_close_mailbox(struct Context *ctx) /* mailbox may not have fully loaded */ if (ctx->hdrs[i] && ctx->hdrs[i]->data) imap_free_header_data((struct ImapHeaderData **) &(ctx->hdrs[i]->data)); - hash_destroy(&idata->uid_hash, NULL); - FREE(&idata->msn_index); - idata->msn_index_size = 0; - - for (i = 0; i < IMAP_CACHE_LEN; i++) - { - if (idata->cache[i].path) - { - unlink(idata->cache[i].path); - FREE(&idata->cache[i].path); - } - } - - mutt_bcache_close(&idata->bcache); return 0; }