mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 10:45:42 +00:00
fix crash when compacting folders, sr=mscott 342236
This commit is contained in:
parent
9a95531c7e
commit
14f5109950
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user