зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
565de27231
Коммит
80238f10a5
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче