Bug #83381 --> crash replying to message with long lines

r=sspitzer
sr=bienvenu
a=asa
This commit is contained in:
mscott%netscape.com 2001-06-06 00:44:06 +00:00
Родитель d608082b01
Коммит 864262f972
3 изменённых файлов: 46 добавлений и 18 удалений

Просмотреть файл

@ -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;