Bug 1494764: Ignore missing \n on last line of last chunk. r=jorgk
authorGene Smith <gds@chartertn.net>
Thu, 25 Oct 2018 00:24:06 -0400
changeset 33601 7a29a83fb1abaeab73083156ebf74f979431be0a
parent 33600 c7094bcea32faad13d115526ddc05991d989bd5e
child 33602 41cd1f527410813bb22fdc7a9e4f5f4a1b2ba761
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersjorgk
bugs1494764
Bug 1494764: Ignore missing \n on last line of last chunk. r=jorgk When last chunk (or only chunk) and last line and it ends in \r and not \r\n, don't expect to see \n on first line of next message fetched. This avoids an assertion failure and functional problem.
mailnews/imap/src/nsImapServerResponseParser.cpp
--- a/mailnews/imap/src/nsImapServerResponseParser.cpp
+++ b/mailnews/imap/src/nsImapServerResponseParser.cpp
@@ -3115,21 +3115,23 @@ bool nsImapServerResponseParser::msg_fet
       // who cares about binary transparency, and anyway \0 in this context violates RFCs.
       charsReadSoFar += strlen(fCurrentLine);
       if (!fDownloadingHeaders && fCurrentCommandIsSingleMessageFetch)
       {
         fServerConnection.ProgressEventFunctionUsingName("imapDownloadingMessage");
         if (fTotalDownloadSize > 0)
           fServerConnection.PercentProgressUpdateEvent(0, charsReadSoFar + origin, fTotalDownloadSize);
       }
-      if (charsReadSoFar > numberOfCharsInThisChunk)
+      if (!lastChunk && (charsReadSoFar > numberOfCharsInThisChunk))
       {
-        // This is the last line of a chunk. "Literal" here means actual email data and
-        // its EOLs, without imap protocol elements and their EOLs. End of line is
-        // defined by two characters \r\n (i.e., CRLF, 0xd,0xa) specified by RFC822.
+        // This is the last line of a chunk but not the last chunk of a multi-chunk
+        // message or the only "chunk" of a smaller non-chunked message. "Literal" here
+        // means actual email data and its EOLs, without imap protocol elements and their
+        // EOLs. End of line is defined by two characters \r\n (i.e., CRLF, 0xd,0xa)
+        // specified by RFC822.
         // Here is an example the most typical last good line of a chunk:
         // "1s8AA5i4AAvF4QAG6+sAAD0bAPsAAAAA1OAAC)\r\n", where ")\r\n" are non-literals.
         // This an example of the last "good" line of a chunk that terminates with \r\n
         // "FxcA/wAAAALN2gADu80ACS0nAPpVVAD1wNAABF5YAPhAJgD31+QABAAAAP8oMQD+HBwA/umj\r\n"
         // followed by another line of non-literal data:
         // " UID 1004)\r\n". These two are concatenated into a single string pointed to
         // by fCurrentLine.  The extra "non-literal data" on the last chunk line makes
         // the charsReadSoFar greater than numberOfCharsInThisChunk (the configured
@@ -3189,29 +3191,29 @@ bool nsImapServerResponseParser::msg_fet
         fServerConnection.HandleMessageDownLoadLine(fCurrentLine, !lastChunk);
         // Restore fCurrentLine's original content.
         displayEndOfLine[1] = saveit1;
         if (fNextChunkStartsWithNewline)
           displayEndOfLine[2] = saveit2;
       }
       else
       {
-        // Not the last line of a chunk.
+        // Not the last line of a chunk or any line when lastChunk.
         if (!fNextChunkStartsWithNewline)
         {
           // Process unmodified fCurrentLine string.
           fServerConnection.HandleMessageDownLoadLine(fCurrentLine,
             !lastChunk && (charsReadSoFar == numberOfCharsInThisChunk),
             fCurrentLine);
         }
         else
         {
           // Ignore the orphan '\n' on a line by itself.
           MOZ_ASSERT(strlen(fCurrentLine) == 1 && fCurrentLine[0] == '\n',
-                     "Expect '\n' as only character in this line");
+                     "Expect '\\n' as only character in this line");
           fNextChunkStartsWithNewline = false;
         }
       }
     }
   }
 
   if (ContinueParse())
   {