[Patchew-devel] [PATCH urgent] views: fix Content-Transfer-Encoding and Content-Type of downloaded mbox

Paolo Bonzini posted 1 patch 5 years, 5 months ago
There is a newer version of this series
www/views.py | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
[Patchew-devel] [PATCH urgent] views: fix Content-Transfer-Encoding and Content-Type of downloaded mbox
Posted by Paolo Bonzini 5 years, 5 months ago
set_payload expects the argument to be already encoded according to the
message's content type and transfer encoding.  Force a good charset
and transfer encoding, in case the source message's is incompatible
with the trailers.

Otherwise, adding an 8-bit trailer to a 7-bit message causes the email
module to switch to quoted-printable, without the body actually being
quoted-printable.  As a result, all equals sign in the original message
are broken.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
	I did not have time to make a testcase for this, but it would
	be nice to have it applied to patchew.org, because /mbox
	is more or less broken currently.  See for example
	https://patchew.org/QEMU/20181126152836.25379-1-rkagan@virtuozzo.com/mbox

 www/views.py | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/www/views.py b/www/views.py
index 5927e61..52ae962 100644
--- a/www/views.py
+++ b/www/views.py
@@ -17,6 +17,7 @@ from django.utils.html import format_html
 from django.conf import settings
 import api
 import email
+import quopri
 from mbox import decode_payload
 import re
 from mod import dispatch_module_hook
@@ -289,14 +290,22 @@ def view_mbox(request, project, message_id):
         try:
             msg = email.message_from_string(mbox)
         except Exception:
-            return mbox
+            return mbox.as_bytes(unixfrom=True)
         container = msg.get_payload(0) if msg.is_multipart() else msg
         if container.get_content_type() != "text/plain":
-            return mbox
+            return mbox.as_bytes(unixfrom=True)
 
         payload = decode_payload(container)
-        container.set_payload('\n'.join(mbox_with_tags_iter(payload, m.tags)))
-        return msg.as_string()
+        # We might be adding 8-bit trailers to a message with 7bit CTE.  For
+        # patches, quoted-printable is safe and mostly human-readable.
+        try:
+            container.replace_header('Content-Transfer-Encoding', 'quoted-printable')
+        except:
+            msg.add_header('Content-Transfer-Encoding', 'quoted-printable')
+        payload = '\n'.join(mbox_with_tags_iter(payload, m.tags))
+        payload = quopri.encodestring(payload.encode('utf-8'))
+        container.set_payload(payload, charset='utf-8')
+        return msg.as_bytes(unixfrom=True)
 
     s = api.models.Message.objects.find_message(message_id, project)
     if not s:
@@ -310,14 +319,8 @@ def view_mbox(request, project, message_id):
 
     mbox_list = []
     for message in messages:
-        mbox_list.append(
-            "From %s %s\n%s" % (
-                message.get_sender_addr(),
-                message.get_asctime(),
-                get_mbox_with_tags(message)
-            )
-        )
-    mbox = "\n".join(mbox_list)
+        mbox_list.append(get_mbox_with_tags(message))
+    mbox = b"\n".join(mbox_list)
     return HttpResponse(mbox, content_type="text/plain")
 
 
-- 
2.19.1

_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel