From bdbeef99674738ae7ff16341fb1f55e8800a7fac Mon Sep 17 00:00:00 2001 From: "bugzilla%standard8.plus.com" Date: Wed, 21 May 2008 07:41:58 +0000 Subject: [PATCH] Bug 434644 Crash [@ nsMsgImapHdrXferInfo::GetHeader] when accessing IMAP folder. r=dmose,sr=bienvenu git-svn-id: svn://10.0.0.236/trunk@251739 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/mailnews/imap/src/nsImapProtocol.cpp | 49 ++++++++++---------- mozilla/mailnews/imap/src/nsImapProtocol.h | 12 ++--- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/mozilla/mailnews/imap/src/nsImapProtocol.cpp b/mozilla/mailnews/imap/src/nsImapProtocol.cpp index 072bcb901ee..acb826a9eb8 100644 --- a/mozilla/mailnews/imap/src/nsImapProtocol.cpp +++ b/mozilla/mailnews/imap/src/nsImapProtocol.cpp @@ -125,9 +125,8 @@ static const PRInt32 kMaxSecondsBeforeCheck = 600; NS_IMPL_THREADSAFE_ISUPPORTS1(nsMsgImapHdrXferInfo, nsIImapHeaderXferInfo) -static const PRInt32 kNumHdrsToXfer=10; - nsMsgImapHdrXferInfo::nsMsgImapHdrXferInfo() + : m_hdrInfos(kNumHdrsToXfer) { m_nextFreeHdrInfo = 0; } @@ -144,6 +143,15 @@ NS_IMETHODIMP nsMsgImapHdrXferInfo::GetNumHeaders(PRInt32 *aNumHeaders) NS_IMETHODIMP nsMsgImapHdrXferInfo::GetHeader(PRInt32 hdrIndex, nsIImapHeaderInfo **aResult) { + // If the header index is more than (or equal to) our next free pointer, then + // its a header we haven't really got and the caller has done something + // wrong. + if (hdrIndex >= m_nextFreeHdrInfo) + { + NS_WARNING("Invalid Header Index requested"); + return NS_ERROR_NULL_POINTER; + } + *aResult = m_hdrInfos.SafeObjectAt(hdrIndex); if (!*aResult) return NS_ERROR_NULL_POINTER; @@ -154,31 +162,24 @@ NS_IMETHODIMP nsMsgImapHdrXferInfo::GetHeader(PRInt32 hdrIndex, nsIImapHeaderInf static const PRInt32 kInitLineHdrCacheSize = 512; // should be about right -nsresult nsMsgImapHdrXferInfo::GetFreeHeaderInfo(nsIImapHeaderInfo **aResult) +nsIImapHeaderInfo* nsMsgImapHdrXferInfo::StartNewHdr() { if (m_nextFreeHdrInfo >= kNumHdrsToXfer) - { - *aResult = nsnull; - return NS_ERROR_NULL_POINTER; - } + return nsnull; - *aResult = m_hdrInfos.SafeObjectAt(m_nextFreeHdrInfo++); - nsresult rv = NS_OK; - if (!*aResult && m_nextFreeHdrInfo - 1 < kNumHdrsToXfer) - { - nsMsgImapLineDownloadCache *lineCache = new nsMsgImapLineDownloadCache(); - if (!lineCache) - return NS_ERROR_OUT_OF_MEMORY; - rv = lineCache->GrowBuffer(kInitLineHdrCacheSize); - NS_ADDREF(*aResult = lineCache); - m_hdrInfos.AppendObject(lineCache); - } - return rv; -} + nsIImapHeaderInfo *result = m_hdrInfos.SafeObjectAt(m_nextFreeHdrInfo++); + if (result) + return result; -void nsMsgImapHdrXferInfo::StartNewHdr(nsIImapHeaderInfo **newHdrInfo) -{ - GetFreeHeaderInfo(newHdrInfo); + nsMsgImapLineDownloadCache *lineCache = new nsMsgImapLineDownloadCache(); + if (!lineCache) + return nsnull; + + lineCache->GrowBuffer(kInitLineHdrCacheSize); + + m_hdrInfos.AppendObject(lineCache); + + return lineCache; } // maybe not needed... @@ -2675,7 +2676,7 @@ nsresult nsImapProtocol::BeginMessageDownLoad( if (m_curHdrInfo) NormalMessageEndDownload(); if (!m_curHdrInfo) - m_hdrDownloadCache->StartNewHdr(getter_AddRefs(m_curHdrInfo)); + m_curHdrInfo = m_hdrDownloadCache->StartNewHdr(); if (m_curHdrInfo) m_curHdrInfo->SetMsgSize(total_message_size); return NS_OK; diff --git a/mozilla/mailnews/imap/src/nsImapProtocol.h b/mozilla/mailnews/imap/src/nsImapProtocol.h index e35e666d06b..bc67b786d1a 100644 --- a/mozilla/mailnews/imap/src/nsImapProtocol.h +++ b/mozilla/mailnews/imap/src/nsImapProtocol.h @@ -119,6 +119,8 @@ private: PRInt32 m_msgSize; }; +#define kNumHdrsToXfer 10 + class nsMsgImapHdrXferInfo : public nsIImapHeaderXferInfo { public: @@ -126,16 +128,14 @@ public: NS_DECL_NSIIMAPHEADERXFERINFO nsMsgImapHdrXferInfo(); virtual ~nsMsgImapHdrXferInfo(); + void ResetAll(); // reset HeaderInfos for re-use + void ReleaseAll(); // release HeaderInfos (frees up memory) // this will return null if we're full, in which case the client code // should transfer the headers and retry. - nsresult GetFreeHeaderInfo(nsIImapHeaderInfo **aResult); - void ResetAll(); // reset HeaderInfo's for re-use - void ReleaseAll(); // release HeaderInfos (frees up memory) - void StartNewHdr(nsIImapHeaderInfo **newHdrInfo); - // get the hdr info we're currently adding lines to - nsIImapHeaderInfo *GetCurrentHdrInfo(); + nsIImapHeaderInfo *StartNewHdr(); // call when we've finished adding lines to current hdr void FinishCurrentHdr(); +private: nsCOMArray m_hdrInfos; PRInt32 m_nextFreeHdrInfo; };