wasm-demo/demo/ermis-f/imap-protocol/cur/1600095123.22903.mbox:2,S

118 lines
4.8 KiB
Plaintext

MBOX-Line: From mrc at CAC.Washington.EDU Tue Jul 31 19:23:48 2007
To: imap-protocol@u.washington.edu
From: Mark Crispin <mrc@CAC.Washington.EDU>
Date: Fri Jun 8 12:34:40 2018
Subject: [Imap-protocol] Re: [Alpine-alpha] problem with "expunge"
In-Reply-To: <Pine.WNT.4.64.0707182348130.2684@name-hqai7p9nl5>
References: <alpine.WNT.0.999.0707181554170.3328@PM-100140.ads.qub.ac.uk>
<alpine.WNT.0.999.0707180959280.2576@Shimo-Tomobiki.Panda.COM>
<Pine.WNT.4.64.0707182348130.2684@name-hqai7p9nl5>
Message-ID: <alpine.LRH.0.999.0707311903340.10533@shiva1.cac.washington.edu>
Thank you for reporting this problem and sending me a debug log. I
apologize for the delay in replying, due to being on vacation.
The underlying problem is with the Exchange server, which is not
implementing the IMAP protocol correctly. The code in Alpine, and the
c-client library called by Alpine, was insufficiently defensive against
invalid protocol from the server.
I am bcc'ing this message to a colleague at Microsoft who used to work on
the IMAP code in Exchange and knows who needs to act on this problem. I
am also cc'ing the IMAP protocol mailing list, so that other IMAP software
developers are aware of the issue.
From your log, early in the session, the Exchange server sent the
following:
IMAP DEBUG 23:44:14.281: * 609 EXISTS
which indicates that there are 609 messages in the mailbox. Later, when
you go to expunge the following happens:
IMAP DEBUG 23:44:35.265: 00000009 EXPUNGE
IMAP DEBUG 23:44:35.343: * 608 EXISTS
IMAP DEBUG 23:44:35.343: * 609 EXPUNGE
IMAP DEBUG 23:44:35.343: 00000009 OK EXPUNGE completed.
This is a big whoops. The
* 608 EXISTS
from the server is invalid, as it shrinks the mailbox. Only an EXPUNGE
can do this. EXISTS can only be sent with a size that is greater than or
equal to the current size. Unfortunately, the c-client library innocently
accepted the shrunken value.
Then, along comes the
* 609 EXPUNGE
which refers to a message that does not exist (since the EXISTS said that
there are only 608 messages). That's why you got the "Unknown message
data: 609 EXPUNGE"; that was defensive code added earlier to defend
against expunging non-existent messages.
A correct scenario would be:
00000009 EXPUNGE
* 609 EXPUNGE
* 608 EXISTS
00000009 OK EXPUNGE completed.
Here, the EXPUNGE removes message 609, and the EXISTS simply confirms that
there are only 608 messages. An equally valid scenario would be:
00000009 EXPUNGE
* 609 EXPUNGE
00000009 OK EXPUNGE completed.
Although the code in c-client protected against the bogus EXPUNGE, it
didn't protect against the bogus EXISTS. Other parts of Alpine still used
the 609 value (remember, the EXPUNGE got disregarded due to the EXISTS).
Thus Alpine and the c-client library disagreed about how many messages
there were, and presently this skew caused the crash (probably something
like "Bad msgno 609 in mail_elt").
The attached patch to alpine/imap/src/c-client/imap4r1.c should protect
against the bogus EXISTS.
However, in order to fully solve the problem, this bug needs to be fixed
in Exchange pronto. It is a bad one, and is likely to foul other IMAP
clients. Hopefully, our friends in Redmond are listening and will get
someone to act on it soon.
-- Mark --
http://staff.washington.edu/mrc
Science does not emerge from voting, party politics, or public debate.
Si vis pacem, para bellum.
-------------- next part --------------
*** imap4r1.c 2007/06/05 21:39:37 1.23
--- imap4r1.c 2007/08/01 02:01:13
***************
*** 967,972 ****
--- 967,973 ----
ambx.type = ASTRING;
ambx.text = (void *) mb.mailbox;
args[0] = &ambx; args[1] = NIL;
+ stream->nmsgs = 0;
if (imap_OK (stream,reply = imap_send (stream,stream->rdonly ?
"EXAMINE": "SELECT",args))) {
strcat (tmp,mb.mailbox);/* mailbox name */
***************
*** 3684,3691 ****
t = strtok_r (NIL,"\n",&r);
/* now take the action */
/* change in size of mailbox */
! if (!strcmp (s,"EXISTS")) mail_exists (stream,msgno);
! else if (!strcmp (s,"RECENT")) mail_recent (stream,msgno);
else if (!strcmp (s,"EXPUNGE") && msgno && (msgno <= stream->nmsgs)) {
mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL);
MESSAGECACHE *elt = (MESSAGECACHE *) (*mc) (stream,msgno,CH_ELT);
--- 3685,3694 ----
t = strtok_r (NIL,"\n",&r);
/* now take the action */
/* change in size of mailbox */
! if (!strcmp (s,"EXISTS") && (msgno >= stream->nmsgs))
! mail_exists (stream,msgno);
! else if (!strcmp (s,"RECENT") && (msgno <= stream->nmsgs))
! mail_recent (stream,msgno);
else if (!strcmp (s,"EXPUNGE") && msgno && (msgno <= stream->nmsgs)) {
mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL);
MESSAGECACHE *elt = (MESSAGECACHE *) (*mc) (stream,msgno,CH_ELT);