Mark Sapiro pushed to branch master at GNU Mailman / Mailman Core


Commits:
f5b889b6 by Mark Sapiro at 2020-11-13T20:57:51-08:00
Handle/Avoid some UnicodeEncodeErrors when creating digests.

- - - - -
9bc78976 by Mark Sapiro at 2020-11-14T20:02:37+00:00
Merge branch 'digest' into 'master'

Handle/Avoid some UnicodeEncodeErrors when creating digests.

Closes #560

See merge request mailman/mailman!729
- - - - -


5 changed files:

- src/mailman/docs/NEWS.rst
- src/mailman/runners/digest.py
- + src/mailman/runners/tests/data/__init__.py
- + src/mailman/runners/tests/data/ascii_in_utf7.eml
- src/mailman/runners/tests/test_digest.py


Changes:

=====================================
src/mailman/docs/NEWS.rst
=====================================
@@ -8,6 +8,15 @@ Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
 Here is a history of user visible changes to Mailman.
 
 
+3.3.3
+=====
+
+(202x-xx-xx)
+
+Bugs
+----
+* Handle some UnicodeEncodeErrors in creating digests.  (Closes #560)
+
 3.3.2
 =====
 


=====================================
src/mailman/runners/digest.py
=====================================
@@ -252,7 +252,9 @@ class RFC1153Digester(Digester):
         # multipart message.  In that case, just stringify it.
         payload = msg.get_payload(decode=True)
         if not payload:
-            payload = msg.as_string().split('\n\n', 1)[1]
+            # Get the message as bytes to avoid UnicodeEncodeError from
+            # as_string() when charset is incorrectly declared.
+            payload = msg.as_bytes().split(b'\n\n', 1)[1]
         if isinstance(payload, bytes):
             try:
                 # Do the decoding inside the try/except so that if the charset
@@ -286,13 +288,14 @@ class RFC1153Digester(Digester):
         print(sign_off, file=self._text)
         print('*' * len(sign_off), file=self._text)
         # If the digest message can't be encoded by the list character set,
-        # fall back to utf-8.
+        # fall back to utf-8 with error replacement.
         text = self._text.getvalue()
         try:
             self._message.set_payload(text.encode(self._charset),
                                       charset=self._charset)
         except UnicodeError:
-            self._message.set_payload(text.encode('utf-8'), charset='utf-8')
+            self._message.set_payload(text.encode('utf-8', errors='replace'),
+                                      charset='utf-8')
         return self._message
 
 


=====================================
src/mailman/runners/tests/data/__init__.py
=====================================


=====================================
src/mailman/runners/tests/data/ascii_in_utf7.eml
=====================================
@@ -0,0 +1,34 @@
+From: u...@example.com
+To: l...@example.com
+Content-Type: text/plain; charset="UTF-7"
+Mime-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+On Fri, 2019-03-01 at 08:02 -0800, Mark S wrote:
++AD4 On 3/1/19 5:00 AM, Jim X via Mailman-cabal wrote:
++AD4 +AD4 Can i haz wiki write permissions?
++AD4 
++AD4 Yes, and now you do.
+
+Thank you,
+
+- -Jim X.
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAEBCgAdFiEECPbAhaBWEfiXj/kxdRlcPb+1fkUFAlx5WHkACgkQdRlcPb+1
+fkWe/w/+PEhOx7gyMjHdGT8hr3dZ2Hcr1PQPnM3h1BK5jE2NbWH4OaUotaes7Lo5
+Wjph4Z8UbJJcaFawqdIJgRbt+kK1HVPWysj69F16XfnZ0ANqE6LzSEzax7eNQJoD
+e2LSvs1YtKKRTDtXyjGgr4F2PjK6tEeuIhs7c1b1Nwp27HMFICh2KWAHEoRAuynI
+s98N3lh5llXg+enbj1RqLFkUGZYv+WZ3x/1oD3OwHLt17BGvNBSHhxKayaUq9mwu
+p6y/CI+Gyx8TAD6MiOplSBIq07zTMv5MhJBlqIZLkb5QGP6ClTNLytANh+aVYLqs
+qi4glr6FlcULDe2/GFv1yr4VphNEj7mxvUNBN+oO4ReQA/4asmG7l+aPDv8cpyWA
+yn//Urhh6GXP7zohvkGVzlMmccgJP7gQTgzpCdA3dNEYyQlDcSvjmehjWyUdGLWV
+X70y8PK1jbHyvkH0u9PpdTiG5JhoWFSpcoI0NdGnzL7prXxOl4fflSinxD0Nf7UD
+Y8CViLpmmqxiwFiDYYGXEzkMyCK7F6kZPgL7PVGUrJOvSXVoIBHvVL7J09s6MnvA
+3qZd/LrgaDjjJVwZrdKvwSxPyat4/Jb/pOETfJJyGANFLdLLfbLZfvcI0JPNWluX
+8tViRnap7tR+NpVn/56SoN/6jVUM8Uxtrrtju80oMvwbTYh2Icc=
+=ZGd6
+-----END PGP SIGNATURE-----


=====================================
src/mailman/runners/tests/test_digest.py
=====================================
@@ -21,8 +21,10 @@ import os
 import re
 import unittest
 
+from email import message_from_binary_file, message_from_bytes
 from email.iterators import _structure as structure
 from email.mime.text import MIMEText
+from importlib_resources import open_binary
 from io import StringIO
 from mailman.app.lifecycle import create_list
 from mailman.config import config
@@ -101,6 +103,52 @@ class TestDigest(unittest.TestCase):
         self.assertEqual(len(self._shuntq.files), 0, error_log.read())
         self._check_virgin_queue()
 
+    def test_utf7_message_with_inline_ascii_sig(self):
+        # The test message is bigger than 1K.  Set the threshold bigger to
+        # avoid double processing in make_digest_messages.
+        self._mlist.digest_size_threshold = 5
+        # Subscribe some users receiving digests.
+        anne = subscribe(self._mlist, 'Anne')
+        anne.preferences.delivery_mode = DeliveryMode.mime_digests
+        bart = subscribe(self._mlist, 'Bart')
+        bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
+        with open_binary('mailman.runners.tests.data',
+                         'ascii_in_utf7.eml') as fp:
+            msg = message_from_binary_file(fp, Message)
+        # Use any error logs as the error message if the test fails.
+        error_log = LogFileMark('mailman.error')
+        make_digest_messages(self._mlist, msg)
+        # The runner will send the file to the shunt queue on exception.
+        self.assertEqual(len(self._shuntq.files), 0, error_log.read())
+        self._check_virgin_queue()
+
+    def test_non_ascii_in_ascii_part(self):
+        # Subscribe some users receiving digests.
+        anne = subscribe(self._mlist, 'Anne')
+        anne.preferences.delivery_mode = DeliveryMode.mime_digests
+        bart = subscribe(self._mlist, 'Bart')
+        bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
+        msg = message_from_bytes(b"""\
+From: a...@example.org
+To: t...@example.com
+Subject: Non-ascii in ascii message
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="abcxyz"
+
+--abcxyz
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 8bit
+
+Don\xe2\x80\x99t try this at home.
+--abcxyz--
+""", Message)
+        # Use any error logs as the error message if the test fails.
+        error_log = LogFileMark('mailman.error')
+        make_digest_messages(self._mlist, msg)
+        # The runner will send the file to the shunt queue on exception.
+        self.assertEqual(len(self._shuntq.files), 0, error_log.read())
+        self._check_virgin_queue()
+
     def test_mime_digest_format(self):
         # Make sure that the format of the MIME digest is as expected.
         self._mlist.digest_size_threshold = 0.6



View it on GitLab: 
https://gitlab.com/mailman/mailman/-/compare/06f8e366cb008ed41595f1948808352fc7be80ed...9bc78976f5b4d1185cd667552133893f23dd36ce

-- 
View it on GitLab: 
https://gitlab.com/mailman/mailman/-/compare/06f8e366cb008ed41595f1948808352fc7be80ed...9bc78976f5b4d1185cd667552133893f23dd36ce
You're receiving this email because of your account on gitlab.com.


_______________________________________________
Mailman-checkins mailing list -- mailman-checkins@python.org
To unsubscribe send an email to mailman-checkins-le...@python.org
https://mail.python.org/mailman3/lists/mailman-checkins.python.org/
Member address: arch...@jab.org

Reply via email to