From f100ebd379aa44e23b7e422d5c329db94d76f782 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 ef8edab6c..752dce41e 100644 --- a/imap/message.c +++ b/imap/message.c @@ -316,7 +316,7 @@ static int msg_fetch_header(struct Context *ctx, struct ImapHeader *h, char *buf /* 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); @@ -375,6 +375,7 @@ int imap_read_headers(struct ImapData *idata, int msgbegin, int msgend) char *hdrreq = NULL; FILE *fp = NULL; char tempfile[_POSIX_PATH_MAX]; + /* TODO: idx should start at ctx->msgcount */ int msgno, idx = msgbegin - 1; struct ImapHeader h; struct ImapStatus *status = NULL; @@ -495,7 +496,7 @@ int imap_read_headers(struct ImapData *idata, int msgbegin, int msgend) { mutt_debug(2, "imap_read_headers: skipping hcache FETCH " "response for unknown message number %d\n", - h.sid); + h.data->msn); mfhrc = -1; continue; } @@ -523,7 +524,7 @@ int imap_read_headers(struct ImapData *idata, int msgbegin, int msgend) else { /* bad header in the cache, we'll have to refetch. */ - mutt_debug(3, "bad cache entry at %d, giving up\n", h.sid - 1); + mutt_debug(3, "bad cache entry at MSN %d, giving up\n", h.data->msn); imap_free_header_data(&h.data); evalhc = 0; idx--; @@ -600,7 +601,7 @@ int imap_read_headers(struct ImapData *idata, int msgbegin, int msgend) { mutt_debug(1, "imap_read_headers: skipping FETCH response for " "unknown message number %d\n", - h.sid); + h.data->msn); mfhrc = -1; idx--; continue; @@ -608,14 +609,14 @@ int imap_read_headers(struct ImapData *idata, int msgbegin, int msgend) /* May receive FLAGS updates in a separate untagged response (#2935) */ if (idx < ctx->msgcount) { - mutt_debug(2, "imap_read_headers: message %d is not new\n", h.sid); + mutt_debug(2, "imap_read_headers: message %d is not new\n", 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 = true; diff --git a/imap/message.h b/imap/message.h index d16ec9ba7..f96942297 100644 --- a/imap/message.h +++ b/imap/message.h @@ -39,13 +39,12 @@ struct ImapHeaderData bool parsed : 1; unsigned int uid; /* 32-bit Message UID */ + unsigned int msn; /* Message Sequence Number */ struct List *keywords; }; struct ImapHeader { - unsigned int sid; - struct ImapHeaderData *data; time_t received; -- 2.40.0