]> granicus.if.org Git - neomutt/commitdiff
Move the IMAP msn field to IMAP_HEADER_DATA. (see #3942)
authorKevin McCarthy <kevin@8t8.us>
Sun, 21 May 2017 01:52:12 +0000 (18:52 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sun, 21 May 2017 01:52:12 +0000 (18:52 -0700)
Ticket 3942 revealed that it is possible for a FETCH to have gaps in
the MSN numbers of the results.  The code makes many assumptions that
equate context index counts and MSN.  This is the first in a series of
commits fixing that assumption.

The header->index field is supposed to hold the SORT_ORDER index
number of the message.  If there are gaps in the MSN, than the highext
MSN can in fact be out of the range 0..ctx->msgcount-1.

After studying the code, I believe curs_main.c would actually work
with header->index values out of the range, at least for IMAP.  But
some other parts of the code, such as mutt_reopen_mailbox(), do rely
on the values being a valid index to ctx->hdrs[].  And the
intertwining of menu->oldcurrent with header->index values makes me
nervous about future changes.

So, to be safe, move the MSN to its own field in IMAP_HEADER_DATA.

The next commit will fix the EXPUNGE behavior.

imap/message.c
imap/message.h

index db6667319581054c058aa903082afb15153b64f8..563db680dbe18c5519e5d5a088a756398353908b 100644 (file)
@@ -80,6 +80,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
   char *hdrreq = NULL;
   FILE *fp;
   char tempfile[_POSIX_PATH_MAX];
+  /* TODO: idx should start at ctx->msgcount */
   int msgno, idx = msgbegin - 1;
   IMAP_HEADER h;
   IMAP_STATUS* status;
@@ -197,7 +198,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
         if (!h.data->uid)
         {
           dprint (2, (debugfile, "imap_read_headers: skipping hcache FETCH "
-                      "response for unknown message number %d\n", h.sid));
+                      "response for unknown message number %d\n", h.data->msn));
           mfhrc = -1;
           continue;
         }
@@ -225,7 +226,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
        else
         {
          /* bad header in the cache, we'll have to refetch. */
-          dprint (3, (debugfile, "bad cache entry at %d, giving up\n", h.sid - 1));
+          dprint (3, (debugfile, "bad cache entry at MSN %d, giving up\n", h.data->msn));
           imap_free_header_data(&h.data);
           evalhc = 0;
           idx--;
@@ -301,7 +302,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
       if (idx > msgend)
       {
         dprint (1, (debugfile, "imap_read_headers: skipping FETCH response for "
-                    "unknown message number %d\n", h.sid));
+                    "unknown message number %d\n", h.data->msn));
         mfhrc = -1;
         idx--;
         continue;
@@ -310,14 +311,14 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
       if (idx < ctx->msgcount)
       {
        dprint (2, (debugfile, "imap_read_headers: message %d is not new\n",
-                   h.sid));
+                   h.data->msn));
         idx--;
        continue;
       }
 
       ctx->hdrs[idx] = mutt_new_header ();
 
-      ctx->hdrs[idx]->index = h.sid - 1;
+      ctx->hdrs[idx]->index = idx;
       /* messages which have not been expunged are ACTIVE (borrowed from mh
        * folders) */
       ctx->hdrs[idx]->active = 1;
@@ -1139,7 +1140,7 @@ static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp)
 
   /* skip to message number */
   buf = imap_next_word (buf);
-  h->sid = atoi (buf);
+  h->data->msn = atoi (buf);
 
   /* find FETCH tag */
   buf = imap_next_word (buf);
index 003bb2e94b31ab3f6ca0fbdad4e5737d60aa57fe..3c5d2cb28f54654f55e2208aab020940b7e315c2 100644 (file)
@@ -37,13 +37,12 @@ typedef struct imap_header_data
   unsigned int parsed : 1;
 
   unsigned int uid;    /* 32-bit Message UID */
+  unsigned int msn;     /* Message Sequence Number */
   LIST *keywords;
 } IMAP_HEADER_DATA;
 
 typedef struct
 {
-  unsigned int sid;
-
   IMAP_HEADER_DATA* data;
 
   time_t received;