diff --git a/mailnews/compose/src/MimeEncoder.jsm b/mailnews/compose/src/MimeEncoder.jsm index 839a42d2fb..18dcfbce7f 100644 --- a/mailnews/compose/src/MimeEncoder.jsm +++ b/mailnews/compose/src/MimeEncoder.jsm @@ -94,7 +94,17 @@ class MimeEncoder { (strictlyMime && this._unPrintableCount) || this._nullCount ) { - encodeP = true; + if ( + this._isMainBody && + this._contentType == "text/plain" && + // From rfc3676#section-4.2, Quoted-Printable encoding SHOULD NOT be + // used with Format=Flowed unless absolutely necessary. + Services.prefs.getBoolPref("mailnews.send_plaintext_flowed") + ) { + needsB64 = true; + } else { + encodeP = true; + } } // MIME requires a special case that these types never be encoded. @@ -408,12 +418,7 @@ class MimeEncoder { if (currentColumn >= 73) { // Soft line break for readability - if (i + 1 < this._bodySize && this._body[i + 1] == " ") { - out += "=20\r\n"; - i++; - } else { - out += "=\r\n"; - } + out += "=\r\n"; white = false; currentColumn = 0; } diff --git a/mailnews/compose/test/unit/test_messageBody.js b/mailnews/compose/test/unit/test_messageBody.js index 708ca0f805..07ce6d279b 100644 --- a/mailnews/compose/test/unit/test_messageBody.js +++ b/mailnews/compose/test/unit/test_messageBody.js @@ -62,13 +62,12 @@ add_task(async function testQP() { "QP for non-ascii should work" ); - // Bug 1689804 - Avoid a QP soft line break before a space. + // Test leading space is preserved. fields = new CompFields(); fields.forceMsgEncoding = true; fields.to = "Nobody "; - fields.subject = - "Bug 1689804 - Save a space to the previous line on a quoted printable soft line break."; + fields.subject = "Leading space is valid in a quoted printable message"; fields.body = "123456789" + " 123456789".repeat(6) + "1234 56789"; await richCreateMessage(fields, [], identity); @@ -81,7 +80,49 @@ add_task(async function testQP() { Assert.equal( body.trimRight("\r\n"), - "123456789 123456789 123456789 123456789 123456789 123456789 1234567891234=20\r\n56789" + "123456789 123456789 123456789 123456789 123456789 123456789 1234567891234=\r\n 56789" + ); + + Services.prefs.clearUserPref("mail.strictly_mime"); +}); + +/** + * Test QP is not used together with format=flowed. + */ +add_task(async function testNoQPWithFormatFlowed() { + if (!Services.prefs.getBoolPref("mailnews.send.jsmodule")) { + return; + } + // Together with fields.forceMsgEncoding, force quote-printable encoding. + Services.prefs.setBoolPref("mail.strictly_mime", true); + + let identity = getSmtpIdentity( + "from@tinderbox.invalid", + getBasicSmtpServer() + ); + let fields = Cc[ + "@mozilla.org/messengercompose/composefields;1" + ].createInstance(Ci.nsIMsgCompFields); + fields.forceMsgEncoding = true; + fields.forcePlainText = true; + fields.to = "Nobody "; + fields.subject = "Test QP encoding for trailing whitespace"; + fields.body = "A line with trailing whitespace\t "; + await richCreateMessage(fields, [], identity); + + let msgData = mailTestUtils.loadMessageToString( + gDraftFolder, + mailTestUtils.firstMsgHdr(gDraftFolder) + ); + Assert.ok( + msgData.includes( + "Content-Type: text/plain; charset=UTF-8; format=flowed\r\nContent-Transfer-Encoding: base64" + ), + "format=flowed should be used" + ); + Assert.ok( + !msgData.includes("quoted-printable"), + "quoted-printable should not be used" ); Services.prefs.clearUserPref("mail.strictly_mime"); diff --git a/mailnews/mime/src/mimeenc.cpp b/mailnews/mime/src/mimeenc.cpp index e2f72a5bec..1c9df3794b 100644 --- a/mailnews/mime/src/mimeenc.cpp +++ b/mailnews/mime/src/mimeenc.cpp @@ -966,11 +966,6 @@ nsresult QPEncoder::Write(const char* buffer, int32_t size) { if (mCurrentColumn >= 73) // Soft line break for readability { *out++ = '='; - if (in + 1 < end && in[1] == ' ') { - in++; - *out++ = '2'; - *out++ = '0'; - } *out++ = '\r'; *out++ = '\n'; diff --git a/mailnews/mime/src/mimemsg.cpp b/mailnews/mime/src/mimemsg.cpp index 7efc659440..fcd86651f7 100644 --- a/mailnews/mime/src/mimemsg.cpp +++ b/mailnews/mime/src/mimemsg.cpp @@ -148,15 +148,6 @@ static int MimeMessage_parse_line(const char* aLine, int32_t aLength, */ nl = (length > 0 && (line[length - 1] == '\r' || line[length - 1] == '\n')); - if (!mime_typep(kid, (MimeObjectClass*)&mimeMessageClass) && obj->options && - !obj->options->is_multipart_msg && !obj->options->decrypt_p && - mime_typep(kid, (MimeObjectClass*)&mimeInlineTextPlainFlowedClass)) { - // Remove any stuffed space. - if (length > 0 && ' ' == *line) { - line++; - length--; - } - } #ifdef MIME_DRAFTS if (!mime_typep(kid, (MimeObjectClass*)&mimeMessageClass) && obj->options && obj->options->decompose_file_p && !obj->options->is_multipart_msg && diff --git a/mailnews/mime/src/mimetpfl.cpp b/mailnews/mime/src/mimetpfl.cpp index 8d1dcbb527..d354217e55 100644 --- a/mailnews/mime/src/mimetpfl.cpp +++ b/mailnews/mime/src/mimetpfl.cpp @@ -277,7 +277,9 @@ static int MimeInlineTextPlainFlowed_parse_line(const char* aLine, const char* linep = real_line.BeginReading(); // Space stuffed? if (' ' == *linep) { + line++; linep++; + length--; } else { // count '>':s before the first non-'>' while ('>' == *linep) {