зеркало из https://github.com/mozilla/pjs.git
fix 166111 patch by ch.ey@gmx.net, r=bienvenu, sr=mscott fix handling of downloading of pop3 messages with non-standard line endings
This commit is contained in:
Родитель
c2b5d9f9c1
Коммит
235a74f646
|
@ -107,7 +107,6 @@ nsMsgLineBuffer::nsMsgLineBuffer(nsMsgLineBufferHandler *handler, PRBool convert
|
||||||
m_handler = handler;
|
m_handler = handler;
|
||||||
m_convertNewlinesP = convertNewlinesP;
|
m_convertNewlinesP = convertNewlinesP;
|
||||||
m_lookingForCRLF = PR_TRUE;
|
m_lookingForCRLF = PR_TRUE;
|
||||||
m_ignoreCRLFs = PR_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsMsgLineBuffer::~nsMsgLineBuffer()
|
nsMsgLineBuffer::~nsMsgLineBuffer()
|
||||||
|
@ -140,43 +139,40 @@ PRInt32 nsMsgLineBuffer::BufferInput(const char *net_buffer, PRInt32 net_buffer_
|
||||||
const char *net_buffer_end = net_buffer + net_buffer_size;
|
const char *net_buffer_end = net_buffer + net_buffer_size;
|
||||||
const char *newline = 0;
|
const char *newline = 0;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
if (!m_ignoreCRLFs)
|
for (s = net_buffer; s < net_buffer_end; s++)
|
||||||
{
|
{
|
||||||
for (s = net_buffer; s < net_buffer_end; s++)
|
if (m_lookingForCRLF) {
|
||||||
{
|
/* Move forward in the buffer until the first newline.
|
||||||
if (m_lookingForCRLF) {
|
Stop when we see CRLF, CR, or LF, or the end of the buffer.
|
||||||
/* Move forward in the buffer until the first newline.
|
*But*, if we see a lone CR at the *very end* of the buffer,
|
||||||
Stop when we see CRLF, CR, or LF, or the end of the buffer.
|
treat this as if we had reached the end of the buffer without
|
||||||
*But*, if we see a lone CR at the *very end* of the buffer,
|
seeing a line terminator. This is to catch the case of the
|
||||||
treat this as if we had reached the end of the buffer without
|
buffers splitting a CRLF pair, as in "FOO\r\nBAR\r" "\nBAZ\r\n".
|
||||||
seeing a line terminator. This is to catch the case of the
|
*/
|
||||||
buffers splitting a CRLF pair, as in "FOO\r\nBAR\r" "\nBAZ\r\n".
|
if (*s == nsCRT::CR || *s == nsCRT::LF) {
|
||||||
*/
|
newline = s;
|
||||||
if (*s == nsCRT::CR || *s == nsCRT::LF) {
|
if (newline[0] == nsCRT::CR) {
|
||||||
newline = s;
|
if (s == net_buffer_end - 1) {
|
||||||
if (newline[0] == nsCRT::CR) {
|
/* CR at end - wait for the next character. */
|
||||||
if (s == net_buffer_end - 1) {
|
newline = 0;
|
||||||
/* CR at end - wait for the next character. */
|
break;
|
||||||
newline = 0;
|
}
|
||||||
break;
|
else if (newline[1] == nsCRT::LF) {
|
||||||
}
|
/* CRLF seen; swallow both. */
|
||||||
else if (newline[1] == nsCRT::LF) {
|
newline++;
|
||||||
/* CRLF seen; swallow both. */
|
|
||||||
newline++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
newline++;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
newline++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
/* if not looking for a CRLF, stop at CR or LF. (for example, when parsing the newsrc file). this fixes #9896, where we'd lose the last line of anything we'd parse that used CR as the line break. */
|
else {
|
||||||
if (*s == nsCRT::CR || *s == nsCRT::LF) {
|
/* if not looking for a CRLF, stop at CR or LF. (for example, when parsing the newsrc file). this fixes #9896, where we'd lose the last line of anything we'd parse that used CR as the line break. */
|
||||||
newline = s;
|
if (*s == nsCRT::CR || *s == nsCRT::LF) {
|
||||||
newline++;
|
newline = s;
|
||||||
break;
|
newline++;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +328,7 @@ void nsMsgLineStreamBuffer::ClearBuffer()
|
||||||
// Note to people wishing to modify this function: Be *VERY CAREFUL* this is a critical function used by all of
|
// Note to people wishing to modify this function: Be *VERY CAREFUL* this is a critical function used by all of
|
||||||
// our mail protocols including imap, nntp, and pop. If you screw it up, you could break a lot of stuff.....
|
// our mail protocols including imap, nntp, and pop. If you screw it up, you could break a lot of stuff.....
|
||||||
|
|
||||||
char * nsMsgLineStreamBuffer::ReadNextLine(nsIInputStream * aInputStream, PRUint32 &aNumBytesInLine, PRBool &aPauseForMoreData, nsresult *prv)
|
char * nsMsgLineStreamBuffer::ReadNextLine(nsIInputStream * aInputStream, PRUint32 &aNumBytesInLine, PRBool &aPauseForMoreData, nsresult *prv, PRBool addLineTerminator)
|
||||||
{
|
{
|
||||||
// try to extract a line from m_inputBuffer. If we don't have an entire line,
|
// try to extract a line from m_inputBuffer. If we don't have an entire line,
|
||||||
// then read more bytes out from the stream. If the stream is empty then wait
|
// then read more bytes out from the stream. If the stream is empty then wait
|
||||||
|
@ -436,7 +432,7 @@ char * nsMsgLineStreamBuffer::ReadNextLine(nsIInputStream * aInputStream, PRUint
|
||||||
aNumBytesInLine--;
|
aNumBytesInLine--;
|
||||||
|
|
||||||
// PR_CALLOC zeros out the allocated line
|
// PR_CALLOC zeros out the allocated line
|
||||||
char* newLine = (char*) PR_CALLOC(aNumBytesInLine+1);
|
char* newLine = (char*) PR_CALLOC(aNumBytesInLine + (addLineTerminator ? MSG_LINEBREAK_LEN : 0) + 1);
|
||||||
if (!newLine)
|
if (!newLine)
|
||||||
{
|
{
|
||||||
aNumBytesInLine = 0;
|
aNumBytesInLine = 0;
|
||||||
|
@ -445,6 +441,11 @@ char * nsMsgLineStreamBuffer::ReadNextLine(nsIInputStream * aInputStream, PRUint
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(newLine, startOfLine, aNumBytesInLine); // copy the string into the new line buffer
|
memcpy(newLine, startOfLine, aNumBytesInLine); // copy the string into the new line buffer
|
||||||
|
if (addLineTerminator)
|
||||||
|
{
|
||||||
|
memcpy(newLine + aNumBytesInLine, MSG_LINEBREAK, MSG_LINEBREAK_LEN);
|
||||||
|
aNumBytesInLine += MSG_LINEBREAK_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_eatCRLFs)
|
if (m_eatCRLFs)
|
||||||
endOfLine += 1; // advance past LF or CR if we haven't already done so...
|
endOfLine += 1; // advance past LF or CR if we haven't already done so...
|
||||||
|
|
|
@ -90,7 +90,6 @@ protected:
|
||||||
nsMsgLineBufferHandler *m_handler;
|
nsMsgLineBufferHandler *m_handler;
|
||||||
PRBool m_convertNewlinesP;
|
PRBool m_convertNewlinesP;
|
||||||
PRBool m_lookingForCRLF;
|
PRBool m_lookingForCRLF;
|
||||||
PRBool m_ignoreCRLFs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// I'm adding this utility class here for lack of a better place. This utility class is similar to nsMsgLineBuffer
|
// I'm adding this utility class here for lack of a better place. This utility class is similar to nsMsgLineBuffer
|
||||||
|
@ -122,7 +121,7 @@ public:
|
||||||
// aEndOfLinetoken -- delimiter used to denote the end of a line.
|
// aEndOfLinetoken -- delimiter used to denote the end of a line.
|
||||||
// aNumBytesInLine -- The number of bytes in the line returned
|
// aNumBytesInLine -- The number of bytes in the line returned
|
||||||
// aPauseForMoreData -- There is not enough data in the stream to make a line at this time...
|
// aPauseForMoreData -- There is not enough data in the stream to make a line at this time...
|
||||||
char * ReadNextLine(nsIInputStream * aInputStream, PRUint32 &anumBytesInLine, PRBool &aPauseForMoreData, nsresult *rv = nsnull);
|
char * ReadNextLine(nsIInputStream * aInputStream, PRUint32 &anumBytesInLine, PRBool &aPauseForMoreData, nsresult *rv = nsnull, PRBool addLineTerminator = PR_FALSE);
|
||||||
nsresult GrowBuffer(PRInt32 desiredSize);
|
nsresult GrowBuffer(PRInt32 desiredSize);
|
||||||
void ClearBuffer();
|
void ClearBuffer();
|
||||||
PRBool NextLineAvailable();
|
PRBool NextLineAvailable();
|
||||||
|
|
|
@ -509,7 +509,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsMsgProtocol)
|
||||||
|
|
||||||
nsPop3Protocol::nsPop3Protocol(nsIURI* aURL)
|
nsPop3Protocol::nsPop3Protocol(nsIURI* aURL)
|
||||||
: nsMsgProtocol(aURL),
|
: nsMsgProtocol(aURL),
|
||||||
nsMsgLineBuffer(NULL, PR_FALSE),
|
|
||||||
m_bytesInMsgReceived(0),
|
m_bytesInMsgReceived(0),
|
||||||
m_totalFolderSize(0),
|
m_totalFolderSize(0),
|
||||||
m_totalDownloadSize(0),
|
m_totalDownloadSize(0),
|
||||||
|
@ -520,8 +519,6 @@ nsPop3Protocol::nsPop3Protocol(nsIURI* aURL)
|
||||||
m_responseTimer(nsnull),
|
m_responseTimer(nsnull),
|
||||||
m_responseTimeout(45)
|
m_responseTimeout(45)
|
||||||
{
|
{
|
||||||
SetLookingForCRLF(MSG_LINEBREAK_LEN == 2);
|
|
||||||
m_ignoreCRLFs = PR_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsPop3Protocol::Initialize(nsIURI * aURL)
|
nsresult nsPop3Protocol::Initialize(nsIURI * aURL)
|
||||||
|
@ -3020,21 +3017,22 @@ nsPop3Protocol::RetrResponse(nsIInputStream* inputStream,
|
||||||
{
|
{
|
||||||
if (m_pop3ConData->msg_closure)
|
if (m_pop3ConData->msg_closure)
|
||||||
{
|
{
|
||||||
m_ignoreCRLFs = PR_TRUE;
|
rv = HandleLine(line, buffer_size);
|
||||||
PRInt32 res = BufferInput(line, buffer_size);
|
if (NS_FAILED(rv))
|
||||||
if (res < 0) return(Error(POP3_MESSAGE_WRITE_ERROR));
|
return (Error(POP3_MESSAGE_WRITE_ERROR));
|
||||||
m_ignoreCRLFs = PR_FALSE;
|
|
||||||
res = BufferInput(MSG_LINEBREAK, MSG_LINEBREAK_LEN);
|
|
||||||
if (res < 0) return(Error(POP3_MESSAGE_WRITE_ERROR));
|
|
||||||
|
|
||||||
|
// not really sure we always had CRLF in input since we
|
||||||
|
// also treat a single LF as line ending!
|
||||||
m_pop3ConData->parsed_bytes += (buffer_size+2); // including CRLF
|
m_pop3ConData->parsed_bytes += (buffer_size+2); // including CRLF
|
||||||
}
|
}
|
||||||
|
|
||||||
// now read in the next line
|
// now read in the next line
|
||||||
PR_Free(line);
|
PR_Free(line);
|
||||||
line = m_lineStreamBuffer->ReadNextLine(inputStream, buffer_size,
|
line = m_lineStreamBuffer->ReadNextLine(inputStream, buffer_size,
|
||||||
pauseForMoreData);
|
pauseForMoreData, &rv, PR_TRUE);
|
||||||
PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
|
PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
|
||||||
|
// not really sure we always had CRLF in input since we
|
||||||
|
// also treat a single LF as line ending!
|
||||||
status += (buffer_size+2); // including CRLF
|
status += (buffer_size+2); // including CRLF
|
||||||
} while (line);
|
} while (line);
|
||||||
}
|
}
|
||||||
|
@ -3068,8 +3066,8 @@ nsPop3Protocol::RetrResponse(nsIInputStream* inputStream,
|
||||||
// (Note: This is only a temp hack until the underlying XPCOM is
|
// (Note: This is only a temp hack until the underlying XPCOM is
|
||||||
// fixed to return errors)
|
// fixed to return errors)
|
||||||
|
|
||||||
if(NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return(Error(POP3_MESSAGE_WRITE_ERROR));
|
return (Error(POP3_MESSAGE_WRITE_ERROR));
|
||||||
|
|
||||||
m_pop3ConData->msg_closure = 0;
|
m_pop3ConData->msg_closure = 0;
|
||||||
}
|
}
|
||||||
|
@ -3195,50 +3193,41 @@ nsPop3Protocol::TopResponse(nsIInputStream* inputStream, PRUint32 length)
|
||||||
return RetrResponse(inputStream, length);
|
return RetrResponse(inputStream, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* line is handed over as null-terminated string with MSG_LINEBREAK */
|
||||||
PRInt32
|
nsresult
|
||||||
nsPop3Protocol::HandleLine(char *line, PRUint32 line_length)
|
nsPop3Protocol::HandleLine(char *line, PRUint32 line_length)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
NS_ASSERTION(m_pop3ConData->msg_closure, "m_pop3ConData->msg_closure is null in nsPop3Protocol::HandleLine()");
|
NS_ASSERTION(m_pop3ConData->msg_closure, "m_pop3ConData->msg_closure is null in nsPop3Protocol::HandleLine()");
|
||||||
if (!m_pop3ConData->msg_closure)
|
if (!m_pop3ConData->msg_closure)
|
||||||
return -1;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
if (!m_senderInfo.IsEmpty() && !m_pop3ConData->seenFromHeader)
|
if (!m_senderInfo.IsEmpty() && !m_pop3ConData->seenFromHeader)
|
||||||
{
|
{
|
||||||
if (line_length > 6 && !PL_strncasecmp("From: ", line, 6))
|
if (line_length > 6 && !PL_strncasecmp("From: ", line, 6))
|
||||||
{
|
{
|
||||||
/* Zzzzz PL_strstr only works with NULL terminated string. Since,
|
|
||||||
* the last character of a line is either a carriage return
|
|
||||||
* or a linefeed. Temporary setting the last character of the
|
|
||||||
* line to NULL and later setting it back should be the right
|
|
||||||
* thing to do.
|
|
||||||
*/
|
|
||||||
char ch = line[line_length-1];
|
|
||||||
line[line_length-1] = 0;
|
|
||||||
m_pop3ConData->seenFromHeader = PR_TRUE;
|
m_pop3ConData->seenFromHeader = PR_TRUE;
|
||||||
if (PL_strstr(line, m_senderInfo.get()) == NULL)
|
if (PL_strstr(line, m_senderInfo.get()) == NULL)
|
||||||
m_nsIPop3Sink->SetSenderAuthedFlag(m_pop3ConData->msg_closure,
|
m_nsIPop3Sink->SetSenderAuthedFlag(m_pop3ConData->msg_closure,
|
||||||
PR_FALSE);
|
PR_FALSE);
|
||||||
line[line_length-1] = ch;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// line contains only dot and linebreak -> message end
|
// line contains only a single dot and linebreak -> message end
|
||||||
if (line[0] == '.' && line_length == 1 + MSG_LINEBREAK_LEN)
|
if (line_length == 1 + MSG_LINEBREAK_LEN && line[0] == '.')
|
||||||
{
|
{
|
||||||
m_pop3ConData->assumed_end = PR_TRUE; /* in case byte count from server is */
|
m_pop3ConData->assumed_end = PR_TRUE; /* in case byte count from server is */
|
||||||
/* wrong, mark we may have had the end */
|
/* wrong, mark we may have had the end */
|
||||||
if (!m_pop3ConData->dot_fix || m_pop3ConData->truncating_cur_msg ||
|
if (!m_pop3ConData->dot_fix || m_pop3ConData->truncating_cur_msg ||
|
||||||
(m_pop3ConData->parsed_bytes >= (m_pop3ConData->pop3_size -3)))
|
(m_pop3ConData->parsed_bytes >= (m_pop3ConData->pop3_size -3)))
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
|
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
|
||||||
nsCOMPtr<nsIMsgWindow> msgWindow;
|
nsCOMPtr<nsIMsgWindow> msgWindow;
|
||||||
if (NS_SUCCEEDED(rv))
|
if (NS_SUCCEEDED(rv))
|
||||||
rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
|
rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
|
||||||
rv = m_nsIPop3Sink->IncorporateComplete(msgWindow,
|
rv = m_nsIPop3Sink->IncorporateComplete(msgWindow,
|
||||||
m_pop3ConData->truncating_cur_msg ? m_pop3ConData->cur_msg_size : 0);
|
m_pop3ConData->truncating_cur_msg ? m_pop3ConData->cur_msg_size : 0);
|
||||||
|
|
||||||
// The following was added to prevent the loss of Data when we try
|
// The following was added to prevent the loss of Data when we try
|
||||||
// and write to somewhere we dont have write access error to (See
|
// and write to somewhere we dont have write access error to (See
|
||||||
|
@ -3246,35 +3235,25 @@ nsPop3Protocol::HandleLine(char *line, PRUint32 line_length)
|
||||||
// (Note: This is only a temp hack until the underlying XPCOM is
|
// (Note: This is only a temp hack until the underlying XPCOM is
|
||||||
// fixed to return errors)
|
// fixed to return errors)
|
||||||
|
|
||||||
if(NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return(Error((rv == NS_MSG_ERROR_COPYING_FROM_TMP_DOWNLOAD)
|
return (Error((rv == NS_MSG_ERROR_COPYING_FROM_TMP_DOWNLOAD)
|
||||||
? POP3_TMP_DOWNLOAD_FAILED
|
? POP3_TMP_DOWNLOAD_FAILED
|
||||||
: POP3_MESSAGE_WRITE_ERROR));
|
: POP3_MESSAGE_WRITE_ERROR));
|
||||||
|
|
||||||
m_pop3ConData->msg_closure = 0;
|
m_pop3ConData->msg_closure = nsnull;
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*When examining a multi-line response, the client checks
|
/* Check if the line begins with the termination octet. If so
|
||||||
to see if the line begins with the termination octet. If so and if
|
and if another termination octet follows, we step over the
|
||||||
octets other than CRLF follow, the first octet of the line (the
|
first occurence of it. */
|
||||||
termination octet) is stripped away.*/
|
else if (line_length > 1 && line[0] == '.' && line[1] == '.') {
|
||||||
else if (line_length > 1 && line[0] == '.' && line[1] == '.' )
|
line++;
|
||||||
{
|
line_length--;
|
||||||
PRUint32 i=0;
|
|
||||||
while ( i < line_length -1 ){
|
|
||||||
line[i] = line[i+1];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
line[i] = '\0';
|
|
||||||
line_length -= 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
rv = m_nsIPop3Sink->IncorporateWrite(line, line_length);
|
|
||||||
if(NS_FAILED(rv))
|
return m_nsIPop3Sink->IncorporateWrite(line, line_length);
|
||||||
return(Error(POP3_MESSAGE_WRITE_ERROR));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt32 nsPop3Protocol::SendDele()
|
PRInt32 nsPop3Protocol::SendDele()
|
||||||
|
|
|
@ -281,7 +281,7 @@ typedef struct _Pop3ConData {
|
||||||
#define POP3_AUTH_FAILURE 0x00000008 /* extended code said authentication failed */
|
#define POP3_AUTH_FAILURE 0x00000008 /* extended code said authentication failed */
|
||||||
|
|
||||||
|
|
||||||
class nsPop3Protocol : public nsMsgProtocol, public nsMsgLineBuffer, public nsIPop3Protocol
|
class nsPop3Protocol : public nsMsgProtocol, public nsIPop3Protocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsPop3Protocol(nsIURI* aURL);
|
nsPop3Protocol(nsIURI* aURL);
|
||||||
|
@ -301,8 +301,6 @@ public:
|
||||||
NS_IMETHOD OnTransportStatus(nsITransport *transport, nsresult status, PRUint32 progress, PRUint32 progressMax);
|
NS_IMETHOD OnTransportStatus(nsITransport *transport, nsresult status, PRUint32 progress, PRUint32 progressMax);
|
||||||
NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports * aContext, nsresult aStatus);
|
NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports * aContext, nsresult aStatus);
|
||||||
NS_IMETHOD Cancel(nsresult status);
|
NS_IMETHOD Cancel(nsresult status);
|
||||||
// for nsMsgLineBuffer
|
|
||||||
virtual PRInt32 HandleLine(char *line, PRUint32 line_length);
|
|
||||||
|
|
||||||
static void MarkMsgInHashTable(PLHashTable *hashTable, const Pop3UidlEntry *uidl,
|
static void MarkMsgInHashTable(PLHashTable *hashTable, const Pop3UidlEntry *uidl,
|
||||||
PRBool *changed);
|
PRBool *changed);
|
||||||
|
@ -365,6 +363,8 @@ private:
|
||||||
void SetResponseTimer();
|
void SetResponseTimer();
|
||||||
void CancelResponseTimer();
|
void CancelResponseTimer();
|
||||||
|
|
||||||
|
nsresult HandleLine(char *line, PRUint32 line_length);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Begin Pop3 protocol state handlers
|
// Begin Pop3 protocol state handlers
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -2422,14 +2422,14 @@ PRInt32 nsNNTPProtocol::BeginArticle()
|
||||||
|
|
||||||
PRInt32 nsNNTPProtocol::DisplayArticle(nsIInputStream * inputStream, PRUint32 length)
|
PRInt32 nsNNTPProtocol::DisplayArticle(nsIInputStream * inputStream, PRUint32 length)
|
||||||
{
|
{
|
||||||
PRUint32 status = 0;
|
PRUint32 line_length = 0;
|
||||||
|
|
||||||
PRBool pauseForMoreData = PR_FALSE;
|
PRBool pauseForMoreData = PR_FALSE;
|
||||||
if (m_channelListener)
|
if (m_channelListener)
|
||||||
{
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
char *line = m_lineStreamBuffer->ReadNextLine(inputStream, status, pauseForMoreData);
|
char *line = m_lineStreamBuffer->ReadNextLine(inputStream, line_length, pauseForMoreData, &rv, PR_TRUE);
|
||||||
if(pauseForMoreData)
|
if (pauseForMoreData)
|
||||||
{
|
{
|
||||||
PRUint32 inlength = 0;
|
PRUint32 inlength = 0;
|
||||||
mDisplayInputStream->Available(&inlength);
|
mDisplayInputStream->Available(&inlength);
|
||||||
|
@ -2437,13 +2437,14 @@ PRInt32 nsNNTPProtocol::DisplayArticle(nsIInputStream * inputStream, PRUint32 le
|
||||||
m_channelListener->OnDataAvailable(this, m_channelContext, mDisplayInputStream, 0, inlength);
|
m_channelListener->OnDataAvailable(this, m_channelContext, mDisplayInputStream, 0, inlength);
|
||||||
SetFlag(NNTP_PAUSE_FOR_READ);
|
SetFlag(NNTP_PAUSE_FOR_READ);
|
||||||
PR_Free(line);
|
PR_Free(line);
|
||||||
return status;
|
return line_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_newsFolder)
|
if (m_newsFolder)
|
||||||
m_newsFolder->NotifyDownloadedLine(line, m_key);
|
m_newsFolder->NotifyDownloadedLine(line, m_key);
|
||||||
|
|
||||||
if (line[0] == '.' && line[1] == 0)
|
// line only contains a single dot -> message end
|
||||||
|
if (line_length == 1 + MSG_LINEBREAK_LEN && line[0] == '.')
|
||||||
{
|
{
|
||||||
m_nextState = NEWS_DONE;
|
m_nextState = NEWS_DONE;
|
||||||
|
|
||||||
|
@ -2454,23 +2455,22 @@ PRInt32 nsNNTPProtocol::DisplayArticle(nsIInputStream * inputStream, PRUint32 le
|
||||||
if (inlength > 0) // broadcast our batched up ODA changes
|
if (inlength > 0) // broadcast our batched up ODA changes
|
||||||
m_channelListener->OnDataAvailable(this, m_channelContext, mDisplayInputStream, 0, inlength);
|
m_channelListener->OnDataAvailable(this, m_channelContext, mDisplayInputStream, 0, inlength);
|
||||||
PR_Free(line);
|
PR_Free(line);
|
||||||
return status;
|
return line_length;
|
||||||
}
|
}
|
||||||
else // we aren't finished with the message yet
|
else // we aren't finished with the message yet
|
||||||
{
|
{
|
||||||
PRUint32 count = 0;
|
PRUint32 count = 0;
|
||||||
|
|
||||||
// skip over the quoted '.'
|
// skip over the quoted '.'
|
||||||
if (line[0] == '.')
|
if (line_length > 1 && line[0] == '.' && line[1] == '.')
|
||||||
mDisplayOutputStream->Write(line+1, PL_strlen(line)-1, &count);
|
mDisplayOutputStream->Write(line+1, line_length-1, &count);
|
||||||
else
|
else
|
||||||
mDisplayOutputStream->Write(line, PL_strlen(line), &count);
|
mDisplayOutputStream->Write(line, line_length, &count);
|
||||||
mDisplayOutputStream->Write(MSG_LINEBREAK, PL_strlen(MSG_LINEBREAK), &count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_Free(line);
|
PR_Free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче