зеркало из https://github.com/mozilla/pjs.git
fix 350179, crash when imap server skips messages when returning flags, nsImapProtocol::NormalMessageEndDownload, sr=mscott
This commit is contained in:
Родитель
d5243ba338
Коммит
17d672c638
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче