This problem was discovered while testing the IMAP UTF-8 mailboxes
patch.

Any feedback from more imap-knowledgeable people would be appreciated.

Thank you.

-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
http://www.8t8.us/configs/gpg-key-transition-statement.txt
# HG changeset patch
# User Kevin McCarthy <[email protected]>
# Date 1441331797 25200
#      Thu Sep 03 18:56:37 2015 -0700
# Node ID e7092e60df0ce52406ecc66a04a073d9a6b14e01
# Parent  bd2c2a6058a7c8fc15ded4815df7ef7119e38ebe
Fix double-decode during IMAP browse.

cmd_parse_list() already calls imap_unmunge_mbox_name() on the mailbox
names returned from the server.  However, browse_add_list_result() was
taking those mailbox names and passing them to imap_add_folder(), which
was calling imap_unmunge_mbox_name() yet again.

The reason is that imap_browse() was directly calling imap_add_folder()
too, passing in a previously encoded "mbox" name.  After looking
carefully at the code, I could find no reason that mbox needed to
be encoded outside of the LIST commands..  Therefore I changed
imap_browse() to call imap_munge_mbox_name() on mbox for the two LIST
commands generated from it instead.

diff --git a/imap/browse.c b/imap/browse.c
--- a/imap/browse.c
+++ b/imap/browse.c
@@ -38,18 +38,18 @@
 
 /* imap_browse: IMAP hook into the folder browser, fills out browser_state,
  *   given a current folder to browse */
 int imap_browse (char* path, struct browser_state* state)
 {
   IMAP_DATA* idata;
   IMAP_LIST list;
   char buf[LONG_STRING];
-  char buf2[LONG_STRING];
   char mbox[LONG_STRING];
+  char munged_mbox[LONG_STRING];
   char list_cmd[5];
   int n;
   int nsup;
   char ctmp;
   short showparents = 0;
   int save_lsub;
   IMAP_MBOX mx;
 
@@ -67,32 +67,27 @@
     goto fail;
 
   mutt_message _("Getting folder list...");
 
   /* skip check for parents when at the root */
   if (mx.mbox && mx.mbox[0] != '\0')
   {
     int rc;
-    char *ptr;
     imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
-    ptr = safe_strdup (mbox);
-    imap_utf_encode (idata, &ptr);
-    mbox[sizeof (mbox) - 1] = '\0';
-    strncpy (mbox, ptr, sizeof (mbox) - 1);
-    FREE (&ptr);
     n = mutt_strlen (mbox);
 
     dprint (3, (debugfile, "imap_browse: mbox: %s\n", mbox));
 
     /* if our target exists and has inferiors, enter it if we
      * aren't already going to */
     if (mbox[n-1] != idata->delim)
     {
-      snprintf (buf, sizeof (buf), "%s \"\" \"%s\"", list_cmd, mbox);
+      imap_munge_mbox_name (idata, munged_mbox, sizeof (munged_mbox), mbox);
+      snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, munged_mbox);
       imap_cmd_start (idata, buf);
       idata->cmdtype = IMAP_CT_LIST;
       idata->cmddata = &list;
       do
       {
        list.name = 0;
         rc = imap_cmd_step (idata);
         if (rc == IMAP_CMD_CONTINUE && list.name)
@@ -175,19 +170,19 @@
     imap_qualify_path (buf, sizeof (buf), &mx, NULL);
     state->folder = safe_strdup (buf);
   }
 
   nsup = state->entrylen;
 
   dprint (3, (debugfile, "imap_browse: Quoting mailbox scan: %s -> ", mbox));
   snprintf (buf, sizeof (buf), "%s%%", mbox);
-  imap_quote_string (buf2, sizeof (buf2), buf);
-  dprint (3, (debugfile, "%s\n", buf2));
-  snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, buf2);
+  imap_munge_mbox_name (idata, munged_mbox, sizeof (munged_mbox), buf);
+  dprint (3, (debugfile, "%s\n", munged_mbox));
+  snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, munged_mbox);
   if (browse_add_list_result (idata, buf, state, 0))
     goto fail;
 
   if (!state->entrylen)
   {
     mutt_error _("No such folder");
     goto fail;
   }
@@ -387,32 +382,31 @@
   }
   while (rc == IMAP_CMD_CONTINUE);
   idata->cmddata = NULL;
 
   FREE (&mx.mbox);
   return rc == IMAP_CMD_OK ? 0 : -1;
 }
 
-/* imap_add_folder: add a folder name to the browser list, formatting it as
- *   necessary. */
+/* imap_add_folder:
+ * add a folder name to the browser list, formatting it as necessary.
+ *
+ * The folder parameter should already be 'unmunged' via
+ * imap_unmunge_mbox_name().
+ */
 static void imap_add_folder (char delim, char *folder, int noselect,
   int noinferiors, struct browser_state *state, short isparent)
 {
   char tmp[LONG_STRING];
   char relpath[LONG_STRING];
   IMAP_MBOX mx;
-  IMAP_DATA* idata;
 
   if (imap_parse_path (state->folder, &mx))
     return;
-  if (!(idata = imap_conn_find (&(mx.account), 0)))
-    return;
-
-  imap_unmunge_mbox_name (idata, folder);
 
   if (state->entrylen + 1 == state->entrymax)
   {
     safe_realloc (&state->entry,
       sizeof (struct folder_file) * (state->entrymax += 256));
     memset (state->entry + state->entrylen, 0,
       (sizeof (struct folder_file) * (state->entrymax - state->entrylen)));
   }

Attachment: signature.asc
Description: PGP signature

Reply via email to