index_operatemailbox() / EXPUNGE bug

David Carter dpc22 at
Mon Oct 5 12:58:59 EDT 2009

Here's a rather nasty little bug in 2.3.15:

   . FETCH 1:2 fast
   * 1 FETCH (FLAGS (\Recent \Deleted \Seen) ...
   * 2 FETCH (FLAGS (\Recent \Seen) ...
   . OK Completed (0.000 sec)

   . SCAN "" a "hello world"
   . OK Completed (0.000 secs 1 calls)

   * 2 EXPUNGE      <--- Whoops, didn't mean that one.
   * 1 EXISTS
   * 1 RECENT
   . OK Completed

The correct message is expunged, imapd just reports the wrong message back 
to the client. Probably PINE or ALPINE given that this is an undocumented 
extension invented by the UW people.

The root cause appears to be index_operatemailbox().

This restores static state in index.c and the global imapd_exists in 
imapd.c based on its mailbox argument, including:

     index_base = mailbox->index_base;
     index_len = mailbox->index_len;

Unfortunately index.c works on the assumption that index_base is a 
private mmaped array (index_dirty = 1, set immediately by index_check()),
so that it can compare the current cyrus.index with the previous version
each time that index_check() is called.

If index_base is just a copy of mailbox->index_base, then index_check() 
remaps both arrays (at least on Linux). You end up comparing two identical 
arrays, but with (mailbox->exists < imapd_exists), which means that 
index_check() is going to generate some untagged EXPUNGE responses.

I attach a nasty patch to fix the SCAN extension by simply saving and then 
restoring all of the globals involved. index_operatemailbox() is called 
from two other functions in imapd.c: catenate_url() and cmd_urlfetch().

David Carter                             Email: David.Carter at
University Computing Service,            Phone: (01223) 334502
New Museums Site, Pembroke Street,       Fax:   (01223) 334679
Cambridge UK. CB2 3QH.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scan.patch
Type: text/x-patch
Size: 3108 bytes
Url : 

More information about the Cyrus-devel mailing list