зеркало из https://github.com/mozilla/gecko-dev.git
Bug #83381 --> crash replying to message with long lines
r=sspitzer sr=bienvenu a=asa
This commit is contained in:
Родитель
d608082b01
Коммит
864262f972
|
@ -779,6 +779,7 @@ public:
|
|||
virtual ~nsMsgFilePostHelper() {}
|
||||
nsCOMPtr<nsIRequest> mPostFileRequest;
|
||||
PRBool mSuspendedPostFileRead;
|
||||
void CloseSocket() { mProtInstance = nsnull; }
|
||||
protected:
|
||||
nsCOMPtr<nsIOutputStream> mOutStream;
|
||||
nsMsgAsyncWriteProtocol * mProtInstance;
|
||||
|
@ -828,6 +829,8 @@ NS_IMETHODIMP nsMsgFilePostHelper::OnStopRequest(nsIRequest * aChannel, nsISuppo
|
|||
|
||||
NS_IMETHODIMP nsMsgFilePostHelper::OnDataAvailable(nsIRequest * /* aChannel */, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
||||
{
|
||||
if (!mProtInstance) return NS_OK;
|
||||
|
||||
if (mSuspendedPostFileRead)
|
||||
{
|
||||
mProtInstance->UpdateSuspendedReadBytes(count, mProtInstance->mInsertPeriodRequired);
|
||||
|
@ -953,6 +956,8 @@ nsresult nsMsgAsyncWriteProtocol::PostDataFinished()
|
|||
|
||||
nsresult nsMsgAsyncWriteProtocol::ProcessIncomingPostData(nsIInputStream *inStr, PRUint32 count)
|
||||
{
|
||||
if (!m_socketIsOpen) return NS_OK; // kick out if the socket was canceled
|
||||
|
||||
// We need to quote any '.' that occur at the beginning of a line.
|
||||
// but I don't want to waste time reading out the data into a buffer and searching
|
||||
// let's try to leverage nsIBufferedInputStream and see if we can "peek" into the
|
||||
|
@ -1021,6 +1026,9 @@ nsresult nsMsgAsyncWriteProtocol::ProcessIncomingPostData(nsIInputStream *inStr,
|
|||
nsresult nsMsgAsyncWriteProtocol::UnblockPostReader()
|
||||
{
|
||||
PRUint32 amountWritten = 0;
|
||||
|
||||
if (!m_socketIsOpen) return NS_OK; // kick out if the socket was canceled
|
||||
|
||||
if (mSuspendedRead)
|
||||
{
|
||||
// (1) attempt to write out any remaining read bytes we need in order to unblock the reader
|
||||
|
@ -1100,6 +1108,25 @@ nsresult nsMsgAsyncWriteProtocol::SetupTransportState()
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgAsyncWriteProtocol::CloseSocket()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsMsgProtocol::CloseSocket();
|
||||
|
||||
// we need to call Cancel so that we remove the socket transport from the mActiveTransportList. see bug #30648
|
||||
if (m_WriteRequest)
|
||||
rv = m_WriteRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
if (mFilePostHelper)
|
||||
{
|
||||
mFilePostHelper->CloseSocket();
|
||||
mFilePostHelper = nsnull;
|
||||
}
|
||||
|
||||
m_WriteRequest = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 nsMsgAsyncWriteProtocol::SendData(nsIURI * aURL, const char * dataBuffer, PRBool aSuppressLogging)
|
||||
{
|
||||
PRUint32 len = nsCRT::strlen(dataBuffer);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
|
@ -63,8 +63,8 @@ public:
|
|||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIREQUEST
|
||||
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// LoadUrl -- A protocol typically overrides this function, sets up any local state for the url and
|
||||
// then calls the base class which opens the socket if it needs opened. If the socket is
|
||||
|
@ -84,16 +84,16 @@ protected:
|
|||
// mscott -okay this is lame. I should break this up into a file protocol and a socket based
|
||||
// protocool class instead of cheating and putting both methods here...
|
||||
|
||||
// open a connection on this url
|
||||
virtual nsresult OpenNetworkSocket(nsIURI * aURL,
|
||||
const char *connectionType,
|
||||
nsIInterfaceRequestor* callbacks);
|
||||
// open a connection on this url
|
||||
virtual nsresult OpenNetworkSocket(nsIURI * aURL,
|
||||
const char *connectionType,
|
||||
nsIInterfaceRequestor* callbacks);
|
||||
|
||||
// open a connection with a specific host and port
|
||||
virtual nsresult OpenNetworkSocketWithInfo(const char * aHostName,
|
||||
PRInt32 aGetPort,
|
||||
const char *connectionType,
|
||||
nsIInterfaceRequestor* callbacks);
|
||||
// open a connection with a specific host and port
|
||||
virtual nsresult OpenNetworkSocketWithInfo(const char * aHostName,
|
||||
PRInt32 aGetPort,
|
||||
const char *connectionType,
|
||||
nsIInterfaceRequestor* callbacks);
|
||||
// helper routine
|
||||
nsresult GetFileFromURL(nsIURI * aURL, nsIFile **aResult);
|
||||
virtual nsresult OpenFileSocket(nsIURI * aURL, PRUint32 aStartPosition, PRInt32 aReadCount); // used to open a file socket connection
|
||||
|
@ -183,8 +183,8 @@ public:
|
|||
// because we are reading the post data in asychronously, it's possible that we aren't sending it
|
||||
// out fast enough and the reading gets blocked. The following set of state variables are used to
|
||||
// track this.
|
||||
PRBool mSuspendedRead;
|
||||
PRBool mInsertPeriodRequired; // do we need to insert a '.' as part of the unblocking process
|
||||
PRBool mSuspendedRead;
|
||||
PRBool mInsertPeriodRequired; // do we need to insert a '.' as part of the unblocking process
|
||||
|
||||
nsresult ProcessIncomingPostData(nsIInputStream *inStr, PRUint32 count);
|
||||
nsresult UnblockPostReader();
|
||||
|
@ -203,12 +203,13 @@ protected:
|
|||
// the streams for the pipe used to queue up data for the async write calls to the server.
|
||||
// we actually re-use the same mOutStream variable in our parent class for the output
|
||||
// stream to the socket channel. So no need for a new variable here.
|
||||
nsCOMPtr<nsIInputStream> mInStream;
|
||||
nsCOMPtr<nsIInputStream> mInStream;
|
||||
nsCOMPtr<nsIInputStream> mPostDataStream;
|
||||
PRUint32 mSuspendedReadBytes; // remaining # of bytes we need to read before
|
||||
// the input stream becomes unblocked
|
||||
PRUint32 mSuspendedReadBytesPostPeriod; // # of bytes which need processed after we insert a '.' before
|
||||
// the input stream becomes unblocked.
|
||||
virtual nsresult CloseSocket();
|
||||
};
|
||||
|
||||
#endif /* nsMsgProtocol_h__ */
|
||||
|
|
|
@ -349,7 +349,7 @@ NS_IMETHODIMP nsSmtpProtocol::OnStopRequest(nsIRequest *request, nsISupports *ct
|
|||
|
||||
// okay, we've been told that the send is done and the connection is going away. So
|
||||
// we need to release all of our state
|
||||
return CloseSocket();
|
||||
return nsMsgAsyncWriteProtocol::CloseSocket();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1499,8 +1499,8 @@ nsresult nsSmtpProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
|||
|
||||
case SMTP_FREE:
|
||||
// smtp is a one time use connection so kill it if we get here...
|
||||
CloseSocket();
|
||||
return NS_OK; /* final end */
|
||||
nsMsgAsyncWriteProtocol::CloseSocket();
|
||||
return NS_OK; /* final end */
|
||||
|
||||
default: /* should never happen !!! */
|
||||
m_nextState = SMTP_ERROR_DONE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче