fix 166111 patch by ch.ey@gmx.net, r=bienvenu, sr=mscott better handling of bad pop3 messages, e.g., with naked line terminators

This commit is contained in:
bienvenu%nventure.com 2004-03-08 17:40:20 +00:00
Родитель 565de27231
Коммит 80238f10a5
3 изменённых файлов: 57 добавлений и 46 удалений

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

@ -107,6 +107,7 @@ nsMsgLineBuffer::nsMsgLineBuffer(nsMsgLineBufferHandler *handler, PRBool convert
m_handler = handler;
m_convertNewlinesP = convertNewlinesP;
m_lookingForCRLF = PR_TRUE;
m_ignoreCRLFs = PR_FALSE;
}
nsMsgLineBuffer::~nsMsgLineBuffer()
@ -131,52 +132,54 @@ PRInt32 nsMsgLineBuffer::BufferInput(const char *net_buffer, PRInt32 net_buffer_
if (m_bufferSize <= m_bufferPos) return -1;
status = ConvertAndSendBuffer();
if (status < 0)
return status;
return status;
m_bufferPos = 0;
}
while (net_buffer_size > 0)
{
{
const char *net_buffer_end = net_buffer + net_buffer_size;
const char *newline = 0;
const char *s;
for (s = net_buffer; s < net_buffer_end; s++)
{
if (m_lookingForCRLF) {
/* Move forward in the buffer until the first newline.
Stop when we see CRLF, CR, or LF, or the end of the buffer.
*But*, if we see a lone CR at the *very end* of the buffer,
treat this as if we had reached the end of the buffer without
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 (newline[0] == nsCRT::CR) {
if (s == net_buffer_end - 1) {
/* CR at end - wait for the next character. */
newline = 0;
break;
}
else if (newline[1] == nsCRT::LF) {
/* CRLF seen; swallow both. */
newline++;
if (!m_ignoreCRLFs)
{
for (s = net_buffer; s < net_buffer_end; s++)
{
if (m_lookingForCRLF) {
/* Move forward in the buffer until the first newline.
Stop when we see CRLF, CR, or LF, or the end of the buffer.
*But*, if we see a lone CR at the *very end* of the buffer,
treat this as if we had reached the end of the buffer without
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 (newline[0] == nsCRT::CR) {
if (s == net_buffer_end - 1) {
/* CR at end - wait for the next character. */
newline = 0;
break;
}
else if (newline[1] == nsCRT::LF) {
/* CRLF seen; swallow both. */
newline++;
}
}
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. */
if (*s == nsCRT::CR || *s == nsCRT::LF) {
newline = s;
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. */
if (*s == nsCRT::CR || *s == nsCRT::LF) {
newline = s;
newline++;
break;
}
}
}
}
/* Ensure room in the net_buffer and append some or all of the current
chunk of data to it. */

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

@ -90,6 +90,7 @@ protected:
nsMsgLineBufferHandler *m_handler;
PRBool m_convertNewlinesP;
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

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

@ -488,6 +488,7 @@ nsPop3Protocol::nsPop3Protocol(nsIURI* aURL)
m_password_already_sent(PR_FALSE)
{
SetLookingForCRLF(MSG_LINEBREAK_LEN == 2);
m_ignoreCRLFs = PR_TRUE;
}
nsresult nsPop3Protocol::Initialize(nsIURI * aURL)
@ -2825,19 +2826,25 @@ nsPop3Protocol::RetrResponse(nsIInputStream* inputStream,
status = buffer_size;
do
{
PRInt32 res = BufferInput(line, buffer_size);
if (res < 0) return(Error(POP3_MESSAGE_WRITE_ERROR));
// BufferInput(CRLF, 2);
res = BufferInput(MSG_LINEBREAK, MSG_LINEBREAK_LEN);
if (res < 0) return(Error(POP3_MESSAGE_WRITE_ERROR));
if (m_pop3ConData->msg_closure)
{
m_ignoreCRLFs = PR_TRUE;
PRInt32 res = BufferInput(line, buffer_size);
if (res < 0) return(Error(POP3_MESSAGE_WRITE_ERROR));
// BufferInput(CRLF, 2);
m_ignoreCRLFs = PR_FALSE;
res = BufferInput(MSG_LINEBREAK, MSG_LINEBREAK_LEN);
if (res < 0) return(Error(POP3_MESSAGE_WRITE_ERROR));
m_pop3ConData->parsed_bytes += (buffer_size+2); // including CRLF
// now read in the next line
PR_Free(line);
line = m_lineStreamBuffer->ReadNextLine(inputStream, buffer_size,
pauseForMoreData);
m_pop3ConData->parsed_bytes += (buffer_size+2); // including CRLF
}
// now read in the next line
PR_Free(line);
line = m_lineStreamBuffer->ReadNextLine(inputStream, buffer_size,
pauseForMoreData);
PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
status += (buffer_size+2); // including CRLF
status += (buffer_size+2); // including CRLF
} while (/* !pauseForMoreData && */ line);
}