Bug#861235: mutt: Very large IMAP folders result in "could not copy message"

2017-07-05 Thread Paul Saunders

Attached is a refreshed patch for mutt 1.8.3+neomutt20170609.
--
vv Email
vvTwitter
da...@darac.org.uk
  Website
^^ XMPP
diff -u mutt-1.8.3+neomutt20170609.orig/imap/command.c mutt-1.8.3+neomutt20170609/imap/command.c
--- mutt-1.8.3+neomutt20170609.orig/imap/command.c	2017-06-09 11:52:07.0 +0100
+++ mutt-1.8.3+neomutt20170609/imap/command.c	2017-07-05 16:07:38.131261224 +0100
@@ -241,7 +241,7 @@
 return;
   }
 
-  mutt_debug(2, "Message UID %d updated\n", HEADER_DATA(h)->uid);
+  mutt_debug(2, "Message UID %u updated\n", HEADER_DATA(h)->uid);
   /* skip FETCH */
   s = imap_next_word(s);
   s = imap_next_word(s);
@@ -491,7 +491,7 @@
 
   while ((s = imap_next_word((char *) s)) && *s != '\0')
   {
-uid = (unsigned int) atoi(s);
+uid = strtoul (s, NULL, 10);
 h = (struct Header *) int_hash_find(idata->uid_hash, uid);
 if (h)
   h->matched = true;
@@ -506,7 +506,7 @@
   char *value = NULL;
   struct Buffy *inc = NULL;
   struct ImapMbox mx;
-  int count;
+  unsigned int count;
   struct ImapStatus *status = NULL;
   unsigned int olduv, oldun;
   long litlen;
@@ -548,7 +548,7 @@
   while (*s && *s != ')')
   {
 value = imap_next_word(s);
-count = strtol(value, , 10);
+count = strtoul(value, , 10);
 
 if (ascii_strncmp("MESSAGES", s, 8) == 0)
 {
@@ -570,7 +570,7 @@
   }
   mutt_debug(
   3,
-  "%s (UIDVALIDITY: %d, UIDNEXT: %d) %d messages, %d recent, %d unseen\n",
+  "%s (UIDVALIDITY: %u, UIDNEXT: %u) %d messages, %d recent, %d unseen\n",
   status->name, status->uidvalidity, status->uidnext, status->messages,
   status->recent, status->unseen);
 
@@ -608,7 +608,7 @@
 
   if (value && (imap_mxcmp(mailbox, value) == 0))
   {
-mutt_debug(3, "Found %s in buffy list (OV: %d ON: %d U: %d)\n", mailbox,
+mutt_debug(3, "Found %s in buffy list (OV: %u ON: %u U: %d)\n", mailbox,
olduv, oldun, status->unseen);
 
 if (option(OPTMAILCHECKRECENT))
diff -u mutt-1.8.3+neomutt20170609.orig/imap/imap.c mutt-1.8.3+neomutt20170609/imap/imap.c
--- mutt-1.8.3+neomutt20170609.orig/imap/imap.c	2017-06-09 11:52:07.0 +0100
+++ mutt-1.8.3+neomutt20170609/imap/imap.c	2017-07-05 16:10:25.748352303 +0100
@@ -281,7 +281,7 @@
 
 if (h->index == INT_MAX)
 {
-  mutt_debug(2, "Expunging message UID %d.\n", HEADER_DATA(h)->uid);
+  mutt_debug(2, "Expunging message UID %u.\n", HEADER_DATA(h)->uid);
 
   h->active = false;
   idata->ctx->size -= h->content->length;
@@ -698,7 +698,7 @@
   mutt_debug(3, "Getting mailbox UIDVALIDITY\n");
   pc += 3;
   pc = imap_next_word(pc);
-  idata->uid_validity = strtol(pc, NULL, 10);
+  idata->uid_validity = strtoul(pc, NULL, 10);
   status->uidvalidity = idata->uid_validity;
 }
 else if (ascii_strncasecmp("OK [UIDNEXT", pc, 11) == 0)
@@ -706,7 +706,7 @@
   mutt_debug(3, "Getting mailbox UIDNEXT\n");
   pc += 3;
   pc = imap_next_word(pc);
-  idata->uidnext = strtol(pc, NULL, 10);
+  idata->uidnext = strtoul(pc, NULL, 10);
   status->uidnext = idata->uidnext;
 }
 else
@@ -1710,7 +1710,7 @@
   if (hc)
   {
 uidvalidity = mutt_hcache_fetch_raw(hc, "/UIDVALIDITY", 12);
-uidnext = mutt_hcache_fetch_raw(hc, "/UIDNEXT", 8);
+uidnext = mutt_hcache_fetch_raw(hc, "/UIDNEXT", 12);
 if (uidvalidity)
 {
   if (!status)
@@ -1722,7 +1722,7 @@
   }
   status->uidvalidity = *(unsigned int *) uidvalidity;
   status->uidnext = uidnext ? *(unsigned int *) uidnext : 0;
-  mutt_debug(3, "mboxcache: hcache uidvalidity %d, uidnext %d\n",
+  mutt_debug(3, "mboxcache: hcache uidvalidity %u, uidnext %u\n",
  status->uidvalidity, status->uidnext);
 }
 mutt_hcache_free(hc, );
diff -u mutt-1.8.3+neomutt20170609.orig/imap/message.c mutt-1.8.3+neomutt20170609/imap/message.c
--- mutt-1.8.3+neomutt20170609.orig/imap/message.c	2017-06-09 11:52:07.0 +0100
+++ mutt-1.8.3+neomutt20170609/imap/message.c	2017-07-05 16:13:25.521600142 +0100
@@ -243,7 +243,7 @@
 {
   s += 3;
   SKIPWS(s);
-  h->data->uid = (unsigned int) atoi(s);
+  h->data->uid = (unsigned int) strtoul (s, NULL, 10);
 
   s = imap_next_word(s);
 }
@@ -315,7 +315,7 @@
 
   /* skip to message number */
   buf = imap_next_word(buf);
-  h->data->msn = atoi(buf);
+  h->data->msn = strtoul (buf, NULL, 10);
 
   /* find FETCH tag */
   buf = imap_next_word(buf);
@@ -531,7 +531,7 @@
   if (idata->hcache && (msn_begin == 1))
   {
 uid_validity = mutt_hcache_fetch_raw(idata->hcache, "/UIDVALIDITY", 12);
-puidnext = mutt_hcache_fetch_raw(idata->hcache, "/UIDNEXT", 8);
+puidnext = mutt_hcache_fetch_raw(idata->hcache, "/UIDNEXT", 12);
 if (puidnext)
 {
   uidnext = *(unsigned int *) puidnext;
@@ -794,7 +794,7 @@
 idata->uidnext = maxuid + 1;
   }
   if (idata->uidnext > 1)
-

Bug#861235: mutt: Very large IMAP folders result in "could not copy message"

2017-05-30 Thread Paul Saunders

Attached is a refreshed patch for mutt 1.8.0.
--
vv Email
vvTwitter
da...@darac.org.uk
  Website
^^ XMPP
diff -u mutt-1.8.0.orig/imap/command.c mutt-1.8.0/imap/command.c
--- mutt-1.8.0.orig/imap/command.c  2017-05-30 09:56:25.0 +0100
+++ mutt-1.8.0/imap/command.c   2017-05-30 09:50:23.177949168 +0100
@@ -640,7 +640,7 @@
   
   if (h && h->active && h->index+1 == msgno)
   {
-   mutt_debug (2, "Message UID %d updated\n", HEADER_DATA(h)->uid);
+   mutt_debug (2, "Message UID %u updated\n", HEADER_DATA(h)->uid);
break;
   }
   
@@ -872,7 +872,7 @@
 
   while ((s = imap_next_word ((char*)s)) && *s != '\0')
   {
-uid = (unsigned int)atoi (s);
+uid = strtoul (s, NULL, 10);
 h = (HEADER *)int_hash_find (idata->uid_hash, uid);
 if (h)
   h->matched = 1;
@@ -887,7 +887,7 @@
   char* value;
   BUFFY* inc;
   IMAP_MBOX mx;
-  int count;
+  unsigned int count;
   IMAP_STATUS *status;
   unsigned int olduv, oldun;
   long litlen;
@@ -929,7 +929,7 @@
   while (*s && *s != ')')
   {
 value = imap_next_word (s);
-count = strtol (value, , 10);
+count = strtoul (value, , 10);
 
 if (!ascii_strncmp ("MESSAGES", s, 8))
 {
@@ -949,7 +949,7 @@
 if (*s && *s != ')')
   s = imap_next_word (s);
   }
-  mutt_debug (3, "%s (UIDVALIDITY: %d, UIDNEXT: %d) %d messages, %d recent, %d unseen\n",
+  mutt_debug (3, "%s (UIDVALIDITY: %u, UIDNEXT: %u) %d messages, %d recent, %d unseen\n",
   status->name, status->uidvalidity, status->uidnext,
   status->messages, status->recent, status->unseen);
 
@@ -988,7 +988,7 @@
 
   if (value && !imap_mxcmp (mailbox, value))
   {
-mutt_debug (3, "Found %s in buffy list (OV: %d ON: %d U: %d)\n",
+mutt_debug (3, "Found %s in buffy list (OV: %u ON: %u U: %d)\n",
 mailbox, olduv, oldun, status->unseen);
 
if (option(OPTMAILCHECKRECENT))
diff -u mutt-1.8.0.orig/imap/imap.c mutt-1.8.0/imap/imap.c
--- mutt-1.8.0.orig/imap/imap.c 2017-05-30 09:56:25.0 +0100
+++ mutt-1.8.0/imap/imap.c  2017-05-30 09:52:28.558686827 +0100
@@ -261,7 +261,7 @@
 
 if (h->index == -1)
 {
-  mutt_debug (2, "Expunging message UID %d.\n", HEADER_DATA (h)->uid);
+  mutt_debug (2, "Expunging message UID %u.\n", HEADER_DATA (h)->uid);
 
   h->active = 0;
   idata->ctx->size -= h->content->length;
@@ -673,7 +673,7 @@
   mutt_debug (3, "Getting mailbox UIDVALIDITY\n");
   pc += 3;
   pc = imap_next_word (pc);
-  idata->uid_validity = strtol (pc, NULL, 10);
+  idata->uid_validity = strtoul (pc, NULL, 10);
   status->uidvalidity = idata->uid_validity;
 }
 else if (ascii_strncasecmp ("OK [UIDNEXT", pc, 11) == 0)
@@ -681,7 +681,7 @@
   mutt_debug (3, "Getting mailbox UIDNEXT\n");
   pc += 3;
   pc = imap_next_word (pc);
-  idata->uidnext = strtol (pc, NULL, 10);
+  idata->uidnext = strtoul (pc, NULL, 10);
   status->uidnext = idata->uidnext;
 }
 else
@@ -1684,7 +1684,7 @@
   if (hc)
   {
 uidvalidity = mutt_hcache_fetch_raw (hc, "/UIDVALIDITY", 12);
-uidnext = mutt_hcache_fetch_raw (hc, "/UIDNEXT", 8);
+uidnext = mutt_hcache_fetch_raw (hc, "/UIDNEXT", 12);
 if (uidvalidity)
 {
   if (!status)
diff -u mutt-1.8.0.orig/imap/message.c mutt-1.8.0/imap/message.c
--- mutt-1.8.0.orig/imap/message.c  2017-05-30 09:56:25.0 +0100
+++ mutt-1.8.0/imap/message.c   2017-05-30 09:55:48.771864749 +0100
@@ -85,7 +85,7 @@
   IMAP_STATUS* status;
   int rc, mfhrc, oldmsgcount;
   int fetchlast = 0;
-  int maxuid = 0;
+  unsigned int maxuid = 0;
   static const char * const want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE CONTENT-DESCRIPTION IN-REPLY-TO REPLY-TO LINES LIST-POST X-LABEL X-KEYWORDS X-MOZILLA-KEYS KEYWORDS X-ORIGINAL-TO";
   progress_t progress;
   int retval = -1;
@@ -142,7 +142,7 @@
   if (idata->hcache && !msgbegin)
   {
 uid_validity = mutt_hcache_fetch_raw (idata->hcache, "/UIDVALIDITY", 12);
-puidnext = mutt_hcache_fetch_raw (idata->hcache, "/UIDNEXT", 8);
+puidnext = mutt_hcache_fetch_raw (idata->hcache, "/UIDNEXT", 12);
 if (puidnext)
 {
   uidnext = *(unsigned int *)puidnext;
@@ -384,7 +384,7 @@
 idata->uidnext = maxuid + 1;
   }
   if (idata->uidnext > 1)
-mutt_hcache_store_raw (idata->hcache, "/UIDNEXT", 8,
+mutt_hcache_store_raw (idata->hcache, "/UIDNEXT", 12,
 >uidnext, sizeof (idata->uidnext));
 
   imap_hcache_close (idata);
@@ -420,8 +420,8 @@
   char *pc;
   long bytes;
   progress_t progressbar, *pbar;
-  int uid;
-  int cacheno;
+  unsigned int uid;
+  unsigned int cacheno;
   IMAP_CACHE *cache;
   int read;
   int rc;
@@ -504,7 +504,7 @@
if (ascii_strncasecmp ("UID", pc, 3) == 0)
{
  pc = imap_next_word (pc);
- uid = atoi (pc);
+ uid = strtoul (pc, NULL, 10);
  if (uid != 

Bug#861235: mutt: Very large IMAP folders result in "could not copy message"

2017-04-26 Thread Paul Saunders
Package: mutt
Version: 1.7.2
Severity: normal
Tags: patch upstream

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA512

Dear Maintainer,

For some reason, one of the mailboxes on my dovecot server has very
large UIDs (> 2**31). Trying to open messages with these very large UIDs
results in mutt complaining "Could not copy message" and failing to open
the message.

Upon investigation, I found that this is because mutt occasionally
treats UIDs as signed integers (the RFC states that they are, in fact,
unsigned ints). In the attached patch, I have tried to track down as
many instances of UIDs being treated as ints as I can (changing
declarations, replacing the use of atoi() with strtoul(), printing with
'%u' instead of '%d' and so on). This now means I can open messages in
the affected mailbox.


- -- Package-specific info:
NeoMutt 20170113 (1.7.2)
Copyright (C) 1996-2016 Michael R. Elkins and others.
Mutt comes with ABSOLUTELY NO WARRANTY; for details type `mutt -vv'.
Mutt is free software, and you are welcome to redistribute it
under certain conditions; type `mutt -vv' for details.

System: Linux 4.9.0-1-686-pae (i686)
libidn: 1.33 (compiled with 1.33)
hcache backends: tokyocabinet

Compiler:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/6/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-14' 
--with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs 
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr 
--program-suffix=-6 --program-prefix=i686-linux-gnu- --enable-shared 
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext 
--enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ 
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes 
--with-default-libstdcxx-abi=new --enable-gnu-unique-object 
--disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie 
--with-system-zlib --disable-browser-plugin --enable-java-awt=gtk 
--enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-i386/jre 
--enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-i386 
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-i386 
--with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar 
--with-target-system-
 zlib --enable-objc-gc=auto --enable-targets=all --enable-multiarch 
--with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-multilib 
--with-tune=generic --enable-checking=release --build=i686-linux-gnu 
--host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 6.3.0 20170415 (Debian 6.3.0-14) 

Configure options: '--build=i686-linux-gnu' '--prefix=/usr' 
'--includedir=\${prefix}/include' '--mandir=\${prefix}/share/man' 
'--infodir=\${prefix}/share/info' '--sysconfdir=/etc' '--localstatedir=/var' 
'--disable-silent-rules' '--libdir=\${prefix}/lib/i386-linux-gnu' 
'--libexecdir=\${prefix}/lib/i386-linux-gnu' '--disable-maintainer-mode' 
'--disable-dependency-tracking' '--with-mailpath=/var/mail' 
'--enable-compressed' '--enable-debug' '--enable-fcntl' '--enable-hcache' 
'--enable-gpgme' '--enable-imap' '--enable-smtp' '--enable-pop' 
'--enable-sidebar' '--enable-nntp' '--enable-notmuch' '--disable-fmemopen' 
'--with-curses' '--with-gnutls' '--with-gss' '--with-idn' '--with-mixmaster' 
'--with-sasl' '--without-gdbm' '--without-bdb' '--without-qdbm' 
'--with-tokyocabinet' 'build_alias=i686-linux-gnu' 'CFLAGS=-g -O2 
-fdebug-prefix-map=/usr/local/src/mutt-1.7.2=. -fstack-protector-strong 
-Wformat -Werror=format-security' 'LDFLAGS=-Wl,-z,relro -Wl,-z,now' 
'CPPFLAGS=-Wdate-time -D_FORTIFY_SOU
 RCE=2'

Compilation CFLAGS: -Wall -pedantic -Wno-long-long -g -O2 
-fdebug-prefix-map=/usr/local/src/mutt-1.7.2=. -fstack-protector-strong 
-Wformat -Werror=format-security -fno-delete-null-pointer-checks

Compile options:
+CRYPT_BACKEND_CLASSIC_PGP +CRYPT_BACKEND_CLASSIC_SMIME +CRYPT_BACKEND_GPGME 
+DEBUG +DL_STANDALONE +ENABLE_NLS -EXACT_ADDRESS -HOMESPOOL -LOCALES_HACK 
- -SUN_ATTACHMENT +HAVE_BKGDSET +HAVE_COLOR +HAVE_CURS_SET +HAVE_FUTIMENS 
+HAVE_GETADDRINFO +HAVE_GETSID +HAVE_ICONV +HAVE_LANGINFO_CODESET 
+HAVE_LANGINFO_YESEXPR +HAVE_LIBIDN +HAVE_META +HAVE_REGCOMP +HAVE_RESIZETERM 
+HAVE_START_COLOR +HAVE_TYPEAHEAD +HAVE_WC_FUNCS +ICONV_NONTRANS 
+USE_COMPRESSED +USE_DOTLOCK +USE_FCNTL -USE_FLOCK -USE_FMEMOPEN -USE_GNU_REGEX 
+USE_GSS +USE_HCACHE +USE_IMAP +USE_NOTMUCH +USE_NNTP +USE_POP +USE_SASL 
+USE_SETGID +USE_SIDEBAR +USE_SMTP +USE_SSL_GNUTLS -USE_SSL_OPENSSL 
- -DOMAIN
MIXMASTER="mixmaster"
ISPELL="/usr/bin/ispell"
SENDMAIL="/usr/sbin/sendmail"
MAILPATH="/var/mail"
PKGDATADIR="/usr/share/mutt"
SYSCONFDIR="/etc"
EXECSHELL="/bin/sh"

patch-attach-headers-color-neomutt
patch-compose-to-sender-neomutt
patch-compress-neomutt
patch-cond-date-neomutt
patch-encrypt-to-self-neomutt
patch-fmemopen-neomutt
patch-forgotten-attachments-neomutt
patch-forwref-neomutt
patch-ifdef-neomutt