From e60090bc9c7e14bb8253eeb64658aedaa0f863c7 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Sun, 10 Nov 2019 18:43:43 -0500 Subject: Bug 1427732 - fix newline handling when copying messages and compacting folders. Tag #1273 --- mailnews/local/src/nsLocalMailFolder.cpp | 40 +++++++++++++++++--------------- mailnews/local/src/nsLocalMailFolder.h | 4 ++++ mailnews/local/src/nsParseMailbox.cpp | 12 ++++++++-- mailnews/local/src/nsParseMailbox.h | 1 + 4 files changed, 36 insertions(+), 21 deletions(-) (limited to 'mailnews/local') diff --git a/mailnews/local/src/nsLocalMailFolder.cpp b/mailnews/local/src/nsLocalMailFolder.cpp index 14135fe46..00244ca87 100644 --- a/mailnews/local/src/nsLocalMailFolder.cpp +++ b/mailnews/local/src/nsLocalMailFolder.cpp @@ -2117,7 +2117,6 @@ nsresult nsMsgLocalMailFolder::WriteStartOfNewMessage() nsresult nsMsgLocalMailFolder::InitCopyMsgHdrAndFileStream() { - nsCOMPtr msgStore; nsresult rv = GetMsgStore(getter_AddRefs(mCopyState->m_msgStore)); NS_ENSURE_SUCCESS(rv, rv); bool reusable; @@ -2387,16 +2386,10 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(bool aCopySucceeded) nsCOMPtr seekableStream(do_QueryInterface(mCopyState->m_fileStream)); if (seekableStream) { - if (mCopyState->m_dummyEnvelopeNeeded) - { - uint32_t bytesWritten; - seekableStream->Seek(nsISeekableStream::NS_SEEK_END, 0); - mCopyState->m_fileStream->Write(MSG_LINEBREAK, MSG_LINEBREAK_LEN, &bytesWritten); - if (mCopyState->m_parseMsgState) - mCopyState->m_parseMsgState->ParseAFolderLine(CRLF, MSG_LINEBREAK_LEN); - } - rv = mCopyState->m_msgStore->FinishNewMessage(mCopyState->m_fileStream, - mCopyState->m_newHdr); + seekableStream->Seek(nsISeekableStream::NS_SEEK_END, 0); + rv = FinishNewLocalMessage(mCopyState->m_fileStream, mCopyState->m_newHdr, + mCopyState->m_msgStore, + mCopyState->m_parseMsgState); if (NS_SUCCEEDED(rv) && mCopyState->m_newHdr) mCopyState->m_newHdr->GetMessageKey(&mCopyState->m_curDstKey); if (multipleCopiesFinished) @@ -2714,13 +2707,9 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndMessage(nsMsgKey key) nsCOMPtr seekableStream = do_QueryInterface(mCopyState->m_fileStream, &rv); NS_ENSURE_SUCCESS(rv, rv); seekableStream->Seek(nsISeekableStream::NS_SEEK_END, 0); - uint32_t bytesWritten; - mCopyState->m_fileStream->Write(MSG_LINEBREAK, MSG_LINEBREAK_LEN, &bytesWritten); - if (mCopyState->m_parseMsgState) - mCopyState->m_parseMsgState->ParseAFolderLine(CRLF, MSG_LINEBREAK_LEN); - - rv = mCopyState->m_msgStore->FinishNewMessage(mCopyState->m_fileStream, - mCopyState->m_newHdr); + rv = FinishNewLocalMessage(mCopyState->m_fileStream, mCopyState->m_newHdr, + mCopyState->m_msgStore, + mCopyState->m_parseMsgState); mCopyState->m_fileStream->Close(); mCopyState->m_fileStream = nullptr; // all done with the file stream @@ -3739,7 +3728,7 @@ nsMsgLocalMailFolder::AddMessageBatch(uint32_t aMessageCount, outFileStream->Write(aMessages[i], messageLen, &bytesWritten); newMailParser->BufferInput(aMessages[i], messageLen); - msgStore->FinishNewMessage(outFileStream, newHdr); + FinishNewLocalMessage(outFileStream, newHdr, msgStore, newMailParser); outFileStream->Close(); outFileStream = nullptr; newMailParser->OnStopRequest(nullptr, nullptr, NS_OK); @@ -3752,6 +3741,19 @@ nsMsgLocalMailFolder::AddMessageBatch(uint32_t aMessageCount, return rv; } +nsresult +nsMsgLocalMailFolder::FinishNewLocalMessage(nsIOutputStream *aOutputStream, + nsIMsgDBHdr *aNewHdr, + nsIMsgPluggableStore *aMsgStore, + nsParseMailMessageState *aParseMsgState) +{ + uint32_t bytesWritten; + aOutputStream->Write(MSG_LINEBREAK, MSG_LINEBREAK_LEN, &bytesWritten); + if (aParseMsgState) + aParseMsgState->ParseAFolderLine(MSG_LINEBREAK, MSG_LINEBREAK_LEN); + return aMsgStore->FinishNewMessage(aOutputStream, aNewHdr); +} + NS_IMETHODIMP nsMsgLocalMailFolder::WarnIfLocalFileTooBig(nsIMsgWindow *aWindow, int64_t aSpaceRequested, diff --git a/mailnews/local/src/nsLocalMailFolder.h b/mailnews/local/src/nsLocalMailFolder.h index e8c395342..b2503a157 100644 --- a/mailnews/local/src/nsLocalMailFolder.h +++ b/mailnews/local/src/nsLocalMailFolder.h @@ -234,6 +234,10 @@ protected: void CopyHdrPropertiesWithSkipList(nsIMsgDBHdr *destHdr, nsIMsgDBHdr *srcHdr, const nsCString &skipList); + nsresult FinishNewLocalMessage(nsIOutputStream *outputStream, + nsIMsgDBHdr *newHdr, + nsIMsgPluggableStore *msgStore, + nsParseMailMessageState *parseMsgState); protected: nsLocalMailCopyState *mCopyState; //We only allow one of these at a time diff --git a/mailnews/local/src/nsParseMailbox.cpp b/mailnews/local/src/nsParseMailbox.cpp index 9d68e5cd1..da51c0322 100644 --- a/mailnews/local/src/nsParseMailbox.cpp +++ b/mailnews/local/src/nsParseMailbox.cpp @@ -598,6 +598,7 @@ NS_IMETHODIMP nsParseMailMessageState::Clear() m_mdn_original_recipient.length = 0; m_bccList.length = 0; m_body_lines = 0; + m_lastLineBlank = 0; m_newMsgHdr = nullptr; m_envelope_pos = 0; m_new_key = nsMsgKey_None; @@ -694,6 +695,9 @@ nsresult nsParseMailMessageState::ParseFolderLine(const char *line, uint32_t lin else if ( m_state == nsIMsgParseMailMsgState::ParseBodyState) { m_body_lines++; + // See comment in msgCore.h for why we use `IS_MSG_LINEBREAK` rather than + // just comparing `line` to `MSG_LINEBREAK`. + m_lastLineBlank = IS_MSG_LINEBREAK(line); } m_position += lineLength; @@ -824,7 +828,9 @@ NS_IMETHODIMP nsParseMailMessageState::FinishHeader() if (m_newMsgHdr) { m_newMsgHdr->SetMessageOffset(m_envelope_pos); - m_newMsgHdr->SetMessageSize(m_position - m_envelope_pos); + if (m_lastLineBlank) + m_body_lines--; + m_newMsgHdr->SetMessageSize(m_position - m_envelope_pos - m_lastLineBlank); m_newMsgHdr->SetLineCount(m_body_lines); } return NS_OK; @@ -1888,7 +1894,9 @@ NS_IMETHODIMP nsParseNewMailState::FinishHeader() { if (m_newMsgHdr) { - m_newMsgHdr->SetMessageSize(m_position - m_envelope_pos); + if (m_lastLineBlank) + m_body_lines--; + m_newMsgHdr->SetMessageSize(m_position - m_envelope_pos - m_lastLineBlank); m_newMsgHdr->SetLineCount(m_body_lines); } return NS_OK; diff --git a/mailnews/local/src/nsParseMailbox.h b/mailnews/local/src/nsParseMailbox.h index 388f1e1b2..aac40611a 100644 --- a/mailnews/local/src/nsParseMailbox.h +++ b/mailnews/local/src/nsParseMailbox.h @@ -115,6 +115,7 @@ public: PRTime m_receivedTime; uint16_t m_body_lines; + uint16_t m_lastLineBlank; bool m_IgnoreXMozillaStatus; -- cgit v1.2.3