fix crash when compacting folders, sr=mscott 342236

This commit is contained in:
bienvenu%nventure.com 2006-06-22 15:52:16 +00:00
parent 9a95531c7e
commit 14f5109950
2 changed files with 39 additions and 9 deletions

View File

@ -628,8 +628,18 @@ nsFolderCompactState::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
{ {
(void) m_curSrcHdr->GetFlags(&msgFlags); (void) m_curSrcHdr->GetFlags(&msgFlags);
(void) m_curSrcHdr->GetStatusOffset(&statusOffset); (void) m_curSrcHdr->GetStatusOffset(&statusOffset);
if (statusOffset == 0) if (statusOffset == 0)
m_needStatusLine = PR_TRUE; m_needStatusLine = PR_TRUE;
// x-mozilla-status lines should be at the start of the headers, and the code
// below assumes everything will fit in m_dataBuffer - if there's not
// room, skip the keyword stuff.
if (statusOffset > sizeof(m_dataBuffer) - 1024)
{
checkForKeyword = PR_FALSE;
NS_ASSERTION(PR_FALSE, "status offset past end of read buffer size");
}
} }
} }
m_startOfMsg = PR_FALSE; m_startOfMsg = PR_FALSE;
@ -637,20 +647,30 @@ nsFolderCompactState::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
PRUint32 maxReadCount, readCount, writeCount; PRUint32 maxReadCount, readCount, writeCount;
while (NS_SUCCEEDED(rv) && (PRInt32) count > 0) while (NS_SUCCEEDED(rv) && (PRInt32) count > 0)
{ {
maxReadCount = count > 4096 ? 4096 : count; maxReadCount = count > sizeof(m_dataBuffer) - 1 ? sizeof(m_dataBuffer) - 1 : count;
writeCount = 0; writeCount = 0;
rv = inStr->Read(m_dataBuffer, maxReadCount, &readCount); rv = inStr->Read(m_dataBuffer, maxReadCount, &readCount);
// if status offset is past the number of bytes we read, it's probably bogus,
// and we shouldn't do any of the keyword stuff.
if (statusOffset + X_MOZILLA_STATUS_LEN > readCount)
checkForKeyword = PR_FALSE;
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
{ {
if (checkForKeyword) if (checkForKeyword)
{ {
const char *keywordHdr = PL_strnrstr(m_dataBuffer, HEADER_X_MOZILLA_KEYWORDS, readCount); // make sure that status offset really points to x-mozilla-status line
if (keywordHdr) if (!strncmp(m_dataBuffer + statusOffset, X_MOZILLA_STATUS, X_MOZILLA_STATUS_LEN))
m_curSrcHdr->GetUint32Property("growKeywords", &needToGrowKeywords); {
else const char *keywordHdr = PL_strnrstr(m_dataBuffer, HEADER_X_MOZILLA_KEYWORDS, readCount);
addKeywordHdr = PR_TRUE; if (keywordHdr)
m_curSrcHdr->GetUint32Property("growKeywords", &needToGrowKeywords);
else
addKeywordHdr = PR_TRUE;
m_curSrcHdr->GetStringProperty("keywords", getter_Copies(msgHdrKeywords));
}
checkForKeyword = PR_FALSE; checkForKeyword = PR_FALSE;
m_curSrcHdr->GetStringProperty("keywords", getter_Copies(msgHdrKeywords));
} }
PRUint32 blockOffset = 0; PRUint32 blockOffset = 0;
if (m_needStatusLine) if (m_needStatusLine)
@ -689,6 +709,8 @@ nsFolderCompactState::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
} }
#define EXTRA_KEYWORD_HDR " "MSG_LINEBREAK #define EXTRA_KEYWORD_HDR " "MSG_LINEBREAK
// if status offset isn't in the first block, this code won't work. There's no good reason
// for the status offset not to be at the beginning of the message anyway.
if (addKeywordHdr) if (addKeywordHdr)
{ {
// if blockOffset is set, we added x-mozilla-status headers so // if blockOffset is set, we added x-mozilla-status headers so
@ -778,8 +800,14 @@ nsFolderCompactState::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
writeCount += blockOffset - preKeywordBlockOffset; // fudge writeCount writeCount += blockOffset - preKeywordBlockOffset; // fudge writeCount
} }
NS_ASSERTION(readCount > blockOffset, "bad block offset"); if (readCount <= blockOffset)
{
NS_ASSERTION(PR_FALSE, "bad block offset");
// not sure what to do to handle this.
}
writeCount += m_fileStream->write(m_dataBuffer + blockOffset, readCount - blockOffset); writeCount += m_fileStream->write(m_dataBuffer + blockOffset, readCount - blockOffset);
printf("writing at offset %d bytes %d string %s\n", blockOffset, readCount - blockOffset, m_dataBuffer+blockOffset);
count -= readCount; count -= readCount;
if (writeCount != readCount) if (writeCount != readCount)
{ {

View File

@ -48,6 +48,8 @@
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsIMsgMessageService.h" #include "nsIMsgMessageService.h"
#define COMPACTOR_READ_BUFF_SIZE 16384
class nsFolderCompactState : public nsIMsgFolderCompactor, public nsIStreamListener, public nsICopyMessageStreamListener, public nsIUrlListener class nsFolderCompactState : public nsIMsgFolderCompactor, public nsIStreamListener, public nsICopyMessageStreamListener, public nsIUrlListener
{ {
public: public:
@ -92,7 +94,7 @@ protected:
PRInt32 m_size; // size of the message key array PRInt32 m_size; // size of the message key array
PRInt32 m_curIndex; // index of the current copied message key in key array PRInt32 m_curIndex; // index of the current copied message key in key array
nsMsgKey m_startOfNewMsg; // offset in mailbox of new message nsMsgKey m_startOfNewMsg; // offset in mailbox of new message
char m_dataBuffer[4096 + 1]; // temp data buffer for copying message char m_dataBuffer[COMPACTOR_READ_BUFF_SIZE + 1]; // temp data buffer for copying message
nsresult m_status; // the status of the copying operation nsresult m_status; // the status of the copying operation
nsCOMPtr <nsIMsgMessageService> m_messageService; // message service for copying nsCOMPtr <nsIMsgMessageService> m_messageService; // message service for copying
nsCOMPtr<nsISupportsArray> m_folderArray; // to store all the folders in case of compact all nsCOMPtr<nsISupportsArray> m_folderArray; // to store all the folders in case of compact all