]> granicus.if.org Git - mutt/commitdiff
Don't clean up idata when closing an open-append mailbox.
authorKevin McCarthy <kevin@8t8.us>
Tue, 23 May 2017 01:18:29 +0000 (18:18 -0700)
committerKevin McCarthy <kevin@8t8.us>
Tue, 23 May 2017 01:18:29 +0000 (18:18 -0700)
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).

imap/imap.c

index f45a516e3642a9a1c7f952fd778630983d5b7686..7b1060a99d78f48b0d8183c831d1ee2617d43b4e 100644 (file)
@@ -1375,6 +1375,14 @@ int imap_close_mailbox (CONTEXT* ctx)
   if (!idata)
     return 0;
 
+  /* imap_open_mailbox_append() borrows the IMAP_DATA 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)
@@ -1390,6 +1398,19 @@ int imap_close_mailbox (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 */
@@ -1397,18 +1418,6 @@ int imap_close_mailbox (CONTEXT* ctx)
     /* mailbox may not have fully loaded */
     if (ctx->hdrs[i] && ctx->hdrs[i]->data)
       imap_free_header_data ((IMAP_HEADER_DATA**)&(ctx->hdrs[i]->data));
-  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);
 
   return 0;
 }