]> granicus.if.org Git - neomutt/commitdiff
Possible fix for random pager crashes.
authorRichard Russon <rich@flatcap.org>
Sun, 23 Oct 2016 17:18:08 +0000 (18:18 +0100)
committerRichard Russon <rich@flatcap.org>
Mon, 24 Oct 2016 14:47:11 +0000 (15:47 +0100)
The crashes have been observed:
- in both local and remote mailboxes
- with/without notmuch
- always are some time has passed
- always have an invalid header pointer

Scenario:
- The Context holds an array of HEADER pointers.
- The pager is given a HEADER to display.
- Time passes and the mailbox changes.

mx_check_mailbox() adds new mails to the end of the Context's array,
calling mx_alloc_memory() if necessary.  The Context's totals are
updated by mx_update_context().

The only way a HEADER pointer could become invalid is if they email were
deleted/moved.  If we detect this has happened, we leave the pager.

curs_main.c
pager.c

index 0bf2fbd33a3550ef5dae1608411525ed6751610f..d12f7079cd141b84f588a14c92e9282ec14743f0 100644 (file)
@@ -1938,7 +1938,7 @@ int mutt_index_menu (void)
 
        menu->menu = MENU_PAGER;
        menu->oldcurrent = menu->current;
-       update_index (menu, Context, MUTT_NEW_MAIL, menu->max, index_hint);
+       update_index (menu, Context, MUTT_NEW_MAIL, Context->msgcount, index_hint);
 
        continue;
 
diff --git a/pager.c b/pager.c
index 19dc2cd84ebf726c9d5e9d466fa4bf69f64dd17b..04f1cdee206650a3740bfd72e2587b01e26719d7 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -1888,6 +1888,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
 #endif
 
     if ((redraw & REDRAW_BODY) || topline != oldtopline)
+             dprint (1, (debugfile, "%p %p\n", extra->hdr, Context->hdrs[Context->v2r[index->current]]));
     {
       do {
         mutt_window_move (pager_window, 0, 0);
@@ -2048,15 +2049,29 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
            }
          }
 
-         if (index)
+         if (index && Context)
          {
-           oldcount = Context ? Context->msgcount : 0;
-           index->max = Context ? Context->vcount : 0;
+           oldcount = Context->msgcount;
+           index->max = Context->vcount;
+
+           /* After the mailbox has been updated,
+            * index->current might be invalid */
+           index->current = MIN(index->current, (Context->msgcount - 1));
            index_hint = Context->hdrs[Context->v2r[index->current]]->index;
+
            int q = Context->quiet;
            Context->quiet = 1;
            update_index (index, Context, check, oldcount, index_hint);
            Context->quiet = q;
+
+           /* If these header pointers don't match, then our email may have
+            * been deleted.  Make the pointer safe, then leave the pager */
+           if (extra->hdr != Context->hdrs[Context->v2r[index->current]])
+           {
+             extra->hdr = Context->hdrs[Context->v2r[index->current]];
+             ch = -1;
+             break;
+           }
          }
 
          redraw = REDRAW_FULL;