From 95c6d0674de68a6f19ab4f86eb779d5124955d95 Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Sat, 20 May 2017 18:52:12 -0700 Subject: [PATCH] Move the IMAP msn field to IMAP_HEADER_DATA. (see #3942) 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 | 13 +++++++------ imap/message.h | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/imap/message.c b/imap/message.c index db666731..563db680 100644 --- a/imap/message.c +++ b/imap/message.c @@ -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); diff --git a/imap/message.h b/imap/message.h index 003bb2e9..3c5d2cb2 100644 --- a/imap/message.h +++ b/imap/message.h @@ -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; -- 2.40.0