fix 350179, crash when imap server skips messages when returning flags, nsImapProtocol::NormalMessageEndDownload, sr=mscott

This commit is contained in:
bienvenu%nventure.com 2006-10-25 14:56:50 +00:00
Родитель d5243ba338
Коммит 17d672c638
4 изменённых файлов: 15 добавлений и 49 удалений

Просмотреть файл

@ -37,7 +37,7 @@
#include "nsISupports.idl"
[scriptable, uuid(70378b9a-6480-11d3-a533-0060b0fc04b7)]
[scriptable, uuid(d4ba3414-fe9e-436b-a01b-bd446e737d04)]
interface nsIImapFlagAndUidState : nsISupports
{
readonly attribute long numberOfMessages;
@ -46,7 +46,7 @@ interface nsIImapFlagAndUidState : nsISupports
void getMessageFlags(in long zeroBasedIndex, out unsigned short result);
void setMessageFlags(in long zeroBasedIndex, in unsigned short flags);
void expungeByIndex(in unsigned long zeroBasedIndex);
void addUidFlagPair(in unsigned long uid, in unsigned short flags);
void addUidFlagPair(in unsigned long uid, in unsigned short flags, in unsigned long zeroBasedIndex);
void addUidCustomFlagPair(in unsigned long uid, in string customFlag);
string getCustomFlags(in unsigned long uid); // returns space-separated keywords
void reset(in unsigned long howManyLeft);

Просмотреть файл

@ -212,61 +212,27 @@ NS_IMETHODIMP nsImapFlagAndUidState::ExpungeByIndex(PRUint32 msgIndex)
// adds to sorted list. protects against duplicates and going past fNumberOfMessageSlotsAllocated
NS_IMETHODIMP nsImapFlagAndUidState::AddUidFlagPair(PRUint32 uid, imapMessageFlagsType flags)
NS_IMETHODIMP nsImapFlagAndUidState::AddUidFlagPair(PRUint32 uid, imapMessageFlagsType flags, PRUint32 zeroBasedIndex)
{
if (uid == nsMsgKey_None) // ignore uid of -1
return NS_OK;
PR_CEnterMonitor(this);
if (zeroBasedIndex > fNumberOfMessagesAdded)
fNumberOfMessagesAdded = zeroBasedIndex + 1;
// make sure there is room for this pair
if (fNumberOfMessagesAdded >= fNumberOfMessageSlotsAllocated)
{
fNumberOfMessageSlotsAllocated += kImapFlagAndUidStateSize;
fUids.SetSize(fNumberOfMessageSlotsAllocated);
fFlags = (imapMessageFlagsType*) PR_REALLOC(fFlags, sizeof(imapMessageFlagsType) * fNumberOfMessageSlotsAllocated); // new imapMessageFlagsType[fNumberOfMessageSlotsAllocated];
if (!fFlags)
return NS_ERROR_OUT_OF_MEMORY;
}
// optimize the common case of placing on the end
if (!fNumberOfMessagesAdded || (uid > (PRUint32) fUids[fNumberOfMessagesAdded - 1]))
{
fUids.SetAt(fNumberOfMessagesAdded, uid);
fFlags[fNumberOfMessagesAdded] = flags;
fNumberOfMessagesAdded++;
if (flags & kImapMsgDeletedFlag)
fNumberDeleted++;
PR_CExitMonitor(this);
return NS_OK;
}
// search for the slot for this uid-flag pair
PRInt32 insertionIndex = -1;
PRBool foundIt = PR_FALSE;
GetMessageFlagsFromUID(uid, &foundIt, &insertionIndex);
// Hmmm, is the server sending back unordered fetch responses?
if (((PRUint32) fUids[insertionIndex]) != uid)
{
// shift the uids and flags to the right
for (PRInt32 shiftIndex = fNumberOfMessagesAdded; shiftIndex > insertionIndex; shiftIndex--)
{
fUids.SetAt(shiftIndex, fUids[shiftIndex - 1]);
fFlags[shiftIndex] = fFlags[shiftIndex - 1];
}
fFlags[insertionIndex] = flags;
fUids.SetAt(insertionIndex, uid);
fNumberOfMessagesAdded++;
if (fFlags[insertionIndex] & kImapMsgDeletedFlag)
fNumberDeleted++;
}
else
{
if ((fFlags[insertionIndex] & kImapMsgDeletedFlag) && !(flags & kImapMsgDeletedFlag))
fNumberDeleted--;
else
if (!(fFlags[insertionIndex] & kImapMsgDeletedFlag) && (flags & kImapMsgDeletedFlag))
fNumberDeleted++;
fFlags[insertionIndex] = flags;
}
fUids.SetAt(zeroBasedIndex, uid);
fFlags[zeroBasedIndex] = flags;
if (flags & kImapMsgDeletedFlag)
fNumberDeleted++;
PR_CExitMonitor(this);
return NS_OK;
}

Просмотреть файл

@ -3985,7 +3985,7 @@ void nsImapMailFolder::FindKeysToDelete(const nsMsgKeyArray &existingKeys, nsMsg
((flags & kImapMsgDeletedFlag) && !showDeletedMessages) )
{
nsMsgKey doomedKey = existingKeys[keyIndex];
if ((PRInt32) doomedKey < 0 && doomedKey != nsMsgKey_None)
if ((PRInt32) doomedKey <= 0 && doomedKey != nsMsgKey_None)
continue;
else
keysToDelete.Add(existingKeys[keyIndex]);
@ -4023,7 +4023,7 @@ void nsImapMailFolder::FindKeysToAdd(const nsMsgKeyArray &existingKeys, nsMsgKey
imapMessageFlagsType flags;
flagState->GetMessageFlags(flagIndex, &flags);
NS_ASSERTION(uidOfMessage != nsMsgKey_None, "got invalid msg key");
if (uidOfMessage != nsMsgKey_None && (showDeletedMessages || ! (flags & kImapMsgDeletedFlag)))
if (uidOfMessage && uidOfMessage != nsMsgKey_None && (showDeletedMessages || ! (flags & kImapMsgDeletedFlag)))
{
if (mDatabase)
{

Просмотреть файл

@ -1322,7 +1322,7 @@ void nsImapServerResponseParser::msg_fetch()
if (CurrentResponseUID() && CurrentResponseUID() != nsMsgKey_None
&& fCurrentLineContainedFlagInfo && fFlagState)
{
fFlagState->AddUidFlagPair(CurrentResponseUID(), fSavedFlagInfo);
fFlagState->AddUidFlagPair(CurrentResponseUID(), fSavedFlagInfo, fFetchResponseIndex - 1);
for (PRInt32 i = 0; i < fCustomFlags.Count(); i++)
fFlagState->AddUidCustomFlagPair(CurrentResponseUID(), fCustomFlags.CStringAt(i)->get());
fCustomFlags.Clear();