diff --git a/mozilla/content/base/src/nsHTMLContentSerializer.cpp b/mozilla/content/base/src/nsHTMLContentSerializer.cpp index 3ac4b269e8f..7685a211bd5 100644 --- a/mozilla/content/base/src/nsHTMLContentSerializer.cpp +++ b/mozilla/content/base/src/nsHTMLContentSerializer.cpp @@ -101,7 +101,7 @@ nsHTMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn, : PR_FALSE; // Set the line break character: if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak) - && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows/mail + && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows mLineBreak.AssignWithConversion("\r\n"); } else if (mFlags & nsIDocumentEncoder::OutputCRLineBreak) { // Mac diff --git a/mozilla/content/base/src/nsPlainTextSerializer.cpp b/mozilla/content/base/src/nsPlainTextSerializer.cpp index 9d43baeab35..699554eaa33 100644 --- a/mozilla/content/base/src/nsPlainTextSerializer.cpp +++ b/mozilla/content/base/src/nsPlainTextSerializer.cpp @@ -162,7 +162,7 @@ nsPlainTextSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn, // Set the line break character: if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak) - && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) // Windows/mail + && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) // Windows mLineBreak.AssignWithConversion("\r\n"); else if (mFlags & nsIDocumentEncoder::OutputCRLineBreak) // Mac mLineBreak.Assign(PRUnichar('\r')); diff --git a/mozilla/mailnews/compose/src/nsMsgSend.cpp b/mozilla/mailnews/compose/src/nsMsgSend.cpp index 56b4772caa8..e84e676cb12 100644 --- a/mozilla/mailnews/compose/src/nsMsgSend.cpp +++ b/mozilla/mailnews/compose/src/nsMsgSend.cpp @@ -1258,7 +1258,7 @@ nsMsgComposeAndSend::GetBodyFromEditor() // char *attachment1_body = nsnull; char *attachment1_type = TEXT_HTML; // we better be "text/html" at this point - PRInt32 attachment1_body_length = 0; + PRUint32 attachment1_body_length = 0; // // Query the editor, get the body of HTML! @@ -1398,6 +1398,86 @@ nsMsgComposeAndSend::GetBodyFromEditor() return rv; } +// for SMTP, 16k +// for our internal protocol buffers, 4k +// for news < 1000 +// so we choose the minimum, because we could be sending and posting this message. +#define LINE_BREAK_MAX 990 + +// EnsureLineBreaks() will set m_attachment1_body and m_attachment1_body_length +nsresult +nsMsgComposeAndSend::EnsureLineBreaks(const char *body, PRUint32 bodyLen) +{ + NS_ENSURE_ARG_POINTER(body); + + PRUint32 i; + PRUint32 charsSinceLineBreak = 0; + PRUint32 lastPos = 0; + + char *newBody = nsnull; + char *newBodyPos = nsnull; + + // the most common way to get into the state where we have to insert + // linebreaks is when we do HTML reply and we quote large
 blocks.
+  // see #83381 and #84261
+  // 
+  // until #67334 is fixed, we'll be replacing newlines with 
, which can lead + // to large quoted
 blocks without linebreaks.
+  // this hack makes it so we can at least save (as draft or template) and send or post
+  // the message.
+  // 
+  // XXX TODO 
+  // march backwards and determine the "best" place for the linebreak
+  // for example, we don't want  or 
+  // or "MississLINEBREAKippi" 
+  for (i = 0; i < bodyLen-1; i++) {
+    if (nsCRT::strncmp(body+i, NS_LINEBREAK, NS_LINEBREAK_LEN)) {
+      charsSinceLineBreak++;
+      if (charsSinceLineBreak == LINE_BREAK_MAX) {
+        if (!newBody) {
+          // in the worse case, the body will be solid, no linebreaks.
+          // that will require us to insert a line break every LINE_BREAK_MAX bytes
+          PRUint32 worstCaseLen = bodyLen+((bodyLen/LINE_BREAK_MAX)*NS_LINEBREAK_LEN);
+          newBody = (char *) PR_Malloc(worstCaseLen);
+          if (!newBody) return NS_ERROR_OUT_OF_MEMORY;
+          newBodyPos = newBody;
+        }
+
+        PL_strncpy(newBodyPos, body+lastPos, i - lastPos + 1);
+        newBodyPos += i - lastPos + 1;
+        PL_strncpy(newBodyPos, NS_LINEBREAK, NS_LINEBREAK_LEN);
+        newBodyPos += NS_LINEBREAK_LEN;
+
+        lastPos = i+1;
+        charsSinceLineBreak = 0;
+      }
+    }
+    else {
+      // found a linebreak
+      charsSinceLineBreak = 0;
+    }
+  }
+
+  // if newBody is non-null is non-zero, we inserted a linebreak
+  if (newBody) {
+     // don't forget about part after the last linebreak we inserted
+     PL_strcpy(newBodyPos, body+lastPos);
+
+     m_attachment1_body = newBody;
+     m_attachment1_body_length = PL_strlen(newBody);  // not worstCaseLen
+  }
+  else {
+     // body did not require any additional linebreaks, so just use it
+     // body will not have any null bytes, so we can use PL_strdup
+     m_attachment1_body = PL_strdup(body);
+     if (!m_attachment1_body) {
+    	return NS_ERROR_OUT_OF_MEMORY;
+     }
+     m_attachment1_body_length = bodyLen;
+  }
+  return NS_OK;
+}
+
 //
 // This is the routine that does the magic of generating the body and the
 // attachments for the multipart/related email message.
@@ -2540,13 +2620,9 @@ nsMsgComposeAndSend::SnarfAndCopyBody(const char  *attachment1_body,
 
     if (attachment1_body_length > 0)
     {
-      char *newb = (char *) PR_Malloc (attachment1_body_length + 1);
-      if (! newb)
-        return NS_ERROR_OUT_OF_MEMORY;
-      nsCRT::memcpy (newb, attachment1_body, attachment1_body_length);
-      newb [attachment1_body_length] = 0;
-      m_attachment1_body = newb;
-      m_attachment1_body_length = attachment1_body_length;
+     // will set m_attachment1_body and m_attachment1_body_length
+     nsresult rv = EnsureLineBreaks(attachment1_body, attachment1_body_length);
+     NS_ENSURE_SUCCESS(rv,rv);
     }
   }
   
diff --git a/mozilla/mailnews/compose/src/nsMsgSend.h b/mozilla/mailnews/compose/src/nsMsgSend.h
index 48928b66ff8..10b304485f0 100644
--- a/mozilla/mailnews/compose/src/nsMsgSend.h
+++ b/mozilla/mailnews/compose/src/nsMsgSend.h
@@ -378,6 +378,9 @@ public:
 protected:
   nsCOMPtr mComposeBundle;
   nsresult GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks);
+private:
+  // will set m_attachment1_body & m_attachment1_body_length;
+  nsresult EnsureLineBreaks(const char *body, PRUint32 body_len);
 };
 
 //