mutt: 2 new changesets

2017-05-12 Thread Brendan Cully
changeset: 7042:a97afb72d892
user:  Kevin McCarthy 
date:  Fri May 12 09:15:00 2017 -0700
link:  http://dev.mutt.org/hg/mutt/rev/a97afb72d892

Turn IMAP_EXPUNGE_EXPECTED back off when syncing. (closes #3940).

imap_sync_mailbox() turned on IMAP_EXPUNGE_EXPECTED when issuing a
EXPUNGE command during a sync.  However, it forgot to turn it back off.

That meant that an unexpected EXPUNGE that occurred during a
mx_check_mailbox -> imap_check_mailbox() -> imap_cmd_finish() call was
not setting
  idata->check_status = IMAP_EXPUNGE_PENDING;
and so imap_check_mailbox() was not returning MUTT_REOPENED.

This meant that although the Context had been changed, the index did
not run update_index(), resulting in a possible segfault.

Thanks to Uroš Juvan for reporting the issue, and his invaluable
description of how to reproduce the problem.

changeset: 7043:149f842ed1d0
user:  Kevin McCarthy 
date:  Fri May 12 09:16:33 2017 -0700
link:  http://dev.mutt.org/hg/mutt/rev/149f842ed1d0

merge stable

diffs (truncated from 5825 to 950 lines):

diff -r 71cb68efe98e -r 149f842ed1d0 addrbook.c
--- a/addrbook.cFri May 05 13:55:31 2017 -0700
+++ b/addrbook.cFri May 12 09:16:33 2017 -0700
@@ -145,15 +145,13 @@
 mutt_error _("You have no aliases!");
 return;
   }
-  
-  /* tell whoever called me to redraw the screen when I return */
-  set_option (OPTNEEDREDRAW);
-  
+
   menu = mutt_new_menu (MENU_ALIAS);
   menu->make_entry = alias_entry;
   menu->tag = alias_tag;
   menu->title = _("Aliases");
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ALIAS, 
AliasHelp);
+  mutt_push_current_menu (menu);
 
 new_aliases:
 
@@ -237,6 +235,7 @@
 rfc822_write_address (buf, buflen, AliasTable[t]->addr, 1);
   }
 
+  mutt_pop_current_menu (menu);
   mutt_menuDestroy (&menu);
   FREE (&AliasTable);
   
diff -r 71cb68efe98e -r 149f842ed1d0 browser.c
--- a/browser.c Fri May 05 13:55:31 2017 -0700
+++ b/browser.c Fri May 12 09:16:33 2017 -0700
@@ -492,17 +492,20 @@
   tmp->msg_unread = Context->unread;
 }
 
+strfcpy (buffer, NONULL (tmp->path), sizeof (buffer));
+mutt_pretty_mailbox (buffer, sizeof (buffer));
+
 #ifdef USE_IMAP
 if (mx_is_imap (tmp->path))
 {
-  add_folder (menu, state, tmp->path, NULL, tmp);
+  add_folder (menu, state, buffer, NULL, tmp);
   continue;
 }
 #endif
 #ifdef USE_POP
 if (mx_is_pop (tmp->path))
 {
-  add_folder (menu, state, tmp->path, NULL, tmp);
+  add_folder (menu, state, buffer, NULL, tmp);
   continue;
 }
 #endif
@@ -528,9 +531,6 @@
s.st_mtime = st2.st_mtime;
 }
 
-strfcpy (buffer, NONULL(tmp->path), sizeof (buffer));
-mutt_pretty_mailbox (buffer, sizeof (buffer));
-
 add_folder (menu, state, buffer, &s, tmp);
   }
   while ((tmp = tmp->next));
@@ -611,7 +611,7 @@
   char helpstr[LONG_STRING];
   char title[STRING];
   struct browser_state state;
-  MUTTMENU *menu;
+  MUTTMENU *menu = NULL;
   struct stat st;
   int i, killPrefix = 0;
   int multiple = (flags & MUTT_SEL_MULTI)  ? 1 : 0;
@@ -722,6 +722,7 @@
 
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER,
 FolderHelp);
+  mutt_push_current_menu (menu);
 
   init_menu (&state, menu, title, sizeof (title), buffy);
 
@@ -908,7 +909,6 @@
}
 
destroy_state (&state);
-   mutt_menuDestroy (&menu);
goto bail;
 
   case OP_BROWSER_TELL:
@@ -954,7 +954,6 @@
  menu->current = 0; 
  menu->top = 0; 
  init_menu (&state, menu, title, sizeof (title), buffy);
- MAYBE_REDRAW (menu->redraw);
}
/* else leave error on screen */
break;
@@ -977,7 +976,6 @@
menu->current = 0;
menu->top = 0;
init_menu (&state, menu, title, sizeof (title), buffy);
-   MAYBE_REDRAW (menu->redraw);
  }
}
break;
@@ -1015,7 +1013,6 @@
  state.entrylen--;
  mutt_message _("Mailbox deleted.");
  init_menu (&state, menu, title, sizeof (title), buffy);
- MAYBE_REDRAW (menu->redraw);
}
  }
  else
@@ -1080,7 +1077,6 @@
  mutt_error _("Error scanning directory.");
  if (examine_directory (menu, &state, LastDir, prefix) == -1)
  {
-   mutt_menuDestroy (&menu);
goto bail;
  }
}
@@ -1095,7 +1091,6 @@
  mutt_perror (buf);
  }
}
-   MAYBE_REDRAW (menu->redraw);
break;

   case OP_ENTER_MASK:
@@ -1151,7 +1146,6 @@
else
{
  mutt_error _("Error scanning directory.");
- mutt_menuDestroy (&menu);
  goto bail;
}
killPrefix = 0;
@@ -1162,7 +1156,6 @@
}
  }
}
-   MAYBE_REDRAW (menu->redraw);
break;
 
   case OP_SORT:
@@ -1246,

Re: [Mutt] #3940: Crash using Gmail over IMAP when copying message to Trash

2017-05-12 Thread Mutt
#3940: Crash using Gmail over IMAP when copying message to Trash
---+-
  Reporter:  kevin8t8  |  Owner:  brendan
  Type:  defect| Status:  closed
  Priority:  major |  Milestone:
 Component:  IMAP  |Version:  1.8.2
Resolution:  fixed |   Keywords:
---+-
Changes (by Kevin McCarthy ):

 * status:  new => closed
 * resolution:   => fixed


Comment:

 In [changeset:"a97afb72d892ec3dc3b75777e516037af9516051"
 7042:a97afb72d892]:
 {{{
 #!CommitTicketReference repository=""
 revision="a97afb72d892ec3dc3b75777e516037af9516051"
 Turn IMAP_EXPUNGE_EXPECTED back off when syncing. (closes #3940).

 imap_sync_mailbox() turned on IMAP_EXPUNGE_EXPECTED when issuing a
 EXPUNGE command during a sync.  However, it forgot to turn it back off.

 That meant that an unexpected EXPUNGE that occurred during a
 mx_check_mailbox -> imap_check_mailbox() -> imap_cmd_finish() call was
 not setting
   idata->check_status = IMAP_EXPUNGE_PENDING;
 and so imap_check_mailbox() was not returning MUTT_REOPENED.

 This meant that although the Context had been changed, the index did
 not run update_index(), resulting in a possible segfault.

 Thanks to Uroš Juvan for reporting the issue, and his invaluable
 description of how to reproduce the problem.
 }}}

--
Ticket URL: 
Mutt 
The Mutt mail user agent



Re: [Mutt] #3940: Crash using Gmail over IMAP when copying message to Trash

2017-05-12 Thread Mutt
#3940: Crash using Gmail over IMAP when copying message to Trash
---+-
  Reporter:  kevin8t8  |  Owner:  brendan
  Type:  defect| Status:  new
  Priority:  major |  Milestone:
 Component:  IMAP  |Version:  1.8.2
Resolution:|   Keywords:
---+-

Comment (by kevin8t8):

 That is great news.  I will push this up to stable, and it will be
 included in the 1.8.3 release in a few weeks.  Thank you for your help!

--
Ticket URL: 
Mutt 
The Mutt mail user agent



Re: [Mutt] #3940: Crash using Gmail over IMAP when copying message to Trash

2017-05-12 Thread Mutt
#3940: Crash using Gmail over IMAP when copying message to Trash
---+--
  Reporter:  kevin8t8  |  Owner:  brendan
  Type:  defect| Status:  reopened
  Priority:  major |  Milestone:
 Component:  IMAP  |Version:  1.8.2
Resolution:|   Keywords:
---+--
Changes (by asmpro@…):

 * status:  closed => reopened
 * resolution:  fixed =>


Comment:

 {{{
 I am glad you found the real problem.
 Still it would be nice to add some safety when accessing non existent
 index in an array :)


 Regards,
 Uros

 On Fri, May 12, 2017 at 04:11:47PM -, Mutt wrote:
 }}}

--
Ticket URL: 
Mutt 
The Mutt mail user agent



Re: [Mutt] #3940: Crash using Gmail over IMAP when copying message to Trash

2017-05-12 Thread Mutt
#3940: Crash using Gmail over IMAP when copying message to Trash
---+-
  Reporter:  kevin8t8  |  Owner:  brendan
  Type:  defect| Status:  closed
  Priority:  major |  Milestone:
 Component:  IMAP  |Version:  1.8.2
Resolution:  fixed |   Keywords:
---+-
Changes (by kevin8t8):

 * status:  reopened => closed
 * resolution:   => fixed


--
Ticket URL: 
Mutt 
The Mutt mail user agent



mutt: 2 new changesets

2017-05-12 Thread Brendan Cully
changeset: 7044:e66c6c0e8cc6
user:  Kevin McCarthy 
date:  Fri May 12 18:31:36 2017 -0700
link:  http://dev.mutt.org/hg/mutt/rev/e66c6c0e8cc6

Add $history_remove_dups option to remove dups from history ring.

When set, duplicate entries will be removed from the history ring when
a new entry is added.  The duplicate removal rearranges the history
ring such that created empty slots are right after the "last" position
in the ring, preserving the most history.

Rewrite the next/prev functions to take into account that blank slots can
now be in the middle of the array.

changeset: 7045:7a4cc1750940
user:  Kevin McCarthy 
date:  Fri May 12 18:31:41 2017 -0700
link:  http://dev.mutt.org/hg/mutt/rev/7a4cc1750940

Also remove duplicates from the history file.

When $history_remove_dups is set, remove duplicates from the history
file when it is periodically compacted.

diffs (364 lines):

diff -r 149f842ed1d0 -r 7a4cc1750940 doc/manual.xml.head
--- a/doc/manual.xml.head   Fri May 12 09:16:33 2017 -0700
+++ b/doc/manual.xml.head   Fri May 12 18:31:41 2017 -0700
@@ -587,7 +587,8 @@
 Mutt maintains a history for the built-in editor.  The number of items
 is controlled by the $history variable
 and can be made persistent using an external file specified using $history_file.  You may cycle through them
+linkend="history-file">$history_file and $save_history.  You may cycle through them
 at an editor prompt by using the 
 and/or  commands.  Mutt will
 remember the currently entered text as you cycle through history, and
@@ -610,9 +611,11 @@
 
 
 Mutt automatically filters out consecutively repeated items from the
-history. It also mimics the behavior of some shells by ignoring items
-starting with a space. The latter feature can be useful in macros to not
-clobber the history's valuable entries with unwanted entries.
+history.  If $history_remove_dups
+is set, all repeated items are removed from the history.  It also mimics the
+behavior of some shells by ignoring items starting with a space. The latter
+feature can be useful in macros to not clobber the history's valuable entries
+with unwanted entries.
 
 
 
diff -r 149f842ed1d0 -r 7a4cc1750940 history.c
--- a/history.c Fri May 12 09:16:33 2017 -0700
+++ b/history.c Fri May 12 18:31:41 2017 -0700
@@ -23,6 +23,46 @@
 #include "mutt.h"
 #include "history.h"
 
+#include 
+
+/* This history ring grows from 0..HistSize, with last marking the
+ * where new entries go:
+ * 0the oldest entry in the ring
+ * 1entry
+ * ...
+ * x-1  most recently entered text
+ *  last-> xNULL  (this will be overwritten next)
+ * x+1  NULL
+ * ...
+ * HistSize NULL
+ *
+ * Once the array fills up, it is used as a ring.  last points where a new
+ * entry will go.  Older entries are "up", and wrap around:
+ * 0entry
+ * 1entry
+ * ...
+ * y-1  most recently entered text
+ *  last-> yentry (this will be overwritten next)
+ * y+1  the oldest entry in the ring
+ * ...
+ * HistSize entry
+ *
+ * When $history_remove_dups is set, duplicate entries are scanned and removed
+ * each time a new entry is added.  In order to preserve the history ring size,
+ * entries 0..last are compacted up.  Entries last+1..HistSize are
+ * compacted down:
+ * 0entry
+ * 1entry
+ * ...
+ * z-1  most recently entered text
+ *  last-> zentry (this will be overwritten next)
+ * z+1  NULL
+ * z+2  NULL
+ * ...
+ *  the oldest entry in the ring
+ *  next oldest entry
+ * HistSize entry
+ */
 struct history
 {
   char **hist;
@@ -94,22 +134,69 @@
   FREE (&linebuf);
 }
 
+static int dup_hash_dec (HASH *dup_hash, char *s)
+{
+  struct hash_elem *elem;
+  uintptr_t count;
+
+  elem = hash_find_elem (dup_hash, s);
+  if (!elem)
+return -1;
+
+  count = (uintptr_t)elem->data;
+  if (count <= 1)
+  {
+hash_delete (dup_hash, s, NULL, NULL);
+return 0;
+  }
+
+  count--;
+  elem->data = (void *)count;
+  return count;
+}
+
+static int dup_hash_inc (HASH *dup_hash, char *s)
+{
+  struct hash_elem *elem;
+  uintptr_t count;
+
+  elem = hash_find_elem (dup_hash, s);
+  if (!elem)
+  {
+count = 1;
+hash_insert (dup_hash, s, (void *)count);
+return count;
+  }
+
+  count = (uintptr_t)elem->data;
+  count++;
+  elem->data = (void *)count;
+  return count;
+}
+
 static void shrink_histfile (void)
 {
   char tmpfname[_POSIX_PATH_MAX];
   FILE *f, *tmp = NULL;
   int n[HC_LAST] = { 0 };
-  int line, hclass;
-  char *linebuf = NULL;
+  int line, hclass, read;
+  char *linebuf = NULL, *p;
   size_t buflen;
+  int regen_file = 0;
+  HASH *dup_hashes[HC_LAST] = { 0 };
 
   if ((f = fopen (HistFile, "r")) == NULL)
 return;
 
+  if (option (OPTHISTREMOVEDUPS))
+