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

Commits:
2c71f67f by Mark Sapiro at 2018-10-30T01:00:55Z
Properly decode message parts when trying to remove Approved:.

- - - - -
31f1ecd9 by Mark Sapiro at 2018-10-30T01:29:05Z
Merge branch 'approve' into 'master'

Properly decode message parts when trying to remove Approved:.

Closes #518

See merge request mailman/mailman!416
- - - - -


3 changed files:

- src/mailman/docs/NEWS.rst
- src/mailman/rules/approved.py
- src/mailman/rules/tests/test_approved.py


Changes:

=====================================
src/mailman/docs/NEWS.rst
=====================================
@@ -27,6 +27,8 @@ Bugs
   (See !407)
 * Autoresponses to posts and -owner and -request messages now work.
   (Closes #504)
+* Message parts are now properly decoded when trying to remove an Approved:
+  header.  (Closes #518)
 
 REST
 ----


=====================================
src/mailman/rules/approved.py
=====================================
@@ -113,8 +113,17 @@ class Approved:
                 # may not work with rtf or whatever else is possible.
                 pattern = (header + r':(\s| )*' + re.escape(password))
                 for part in typed_subpart_iterator(msg, 'text'):
-                    payload = part.get_payload()
+                    payload = part.get_payload(decode=True)
                     if payload is not None:
+                        charset = part.get_content_charset('us-ascii')
+                        try:
+                            # Do the decoding inside the try/except so that if
+                            # the charset is unknown, we'll just drop back to
+                            # ascii.
+                            payload = payload.decode(charset, 'replace')
+                        except LookupError:
+                            # Unknown or empty charset.
+                            payload = payload.decode('us-ascii', 'replace')
                         if re.search(pattern, payload):
                             reset_payload(part, re.sub(pattern, '', payload))
         else:
@@ -138,7 +147,10 @@ def reset_payload(part, payload):
     delsp = part.get_param('delsp')
     del part['content-transfer-encoding']
     del part['content-type']
-    part.set_payload(payload, charset)
+    try:
+        part.set_payload(payload, charset)
+    except LookupError:
+        part.set_payload(payload, 'us-ascii')
     part.set_type(content_type)
     if format:
         part.set_param('Format', format)


=====================================
src/mailman/rules/tests/test_approved.py
=====================================
@@ -531,3 +531,59 @@ Content-Transfer-Encoding: 7bit
 """)
         result = self._rule.check(self._mlist, msg, {})
         self.assertFalse(result)
+
+
+class TestProperDecodingOfAllParts(unittest.TestCase):
+    """Test that the approved handler properly decodes all message parts."""
+
+    layer = ConfigLayer
+
+    def setUp(self):
+        self._mlist = create_list('t...@example.com')
+        self._mlist.moderator_password = config.password_context.encrypt(
+            'super secret')
+        self._rule = approved.Approved()
+        self._msg_text = """\
+From: a...@example.com
+To: t...@example.com
+Subject: A Message with non-ascii body
+Message-ID: <ant>
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="AAA"
+
+--AAA
+Content-Type: text/plain
+Content-Transfer-Encoding: quoted-printable
+
+Approved: super secret
+The above line will be removed=21
+
+--AAA
+Content-Type: text/html{}
+Content-Transfer-Encoding: quoted-printable
+
+
+<div dir=3D"ltr"><div>Approved:super=20secret</div><div>The =
+password approval will be removed=21</div></div>
+
+"""
+
+    def test_proper_decoding_mime(self):
+        msg = mfs(self._msg_text.format(''))
+        result = self._rule.check(self._mlist, msg, {})
+        self.assertTrue(result)
+        self.assertEqual(b'The above line will be removed!\n',
+                         msg.get_payload(0).get_payload(decode=True))
+        self.assertEqual(b'\n<div dir="ltr"><div></div><div>The password '
+                         b'approval will be removed!</div></div>\n',
+                         msg.get_payload(1).get_payload(decode=True))
+
+    def test_proper_decoding_mime_unknown_charset(self):
+        msg = mfs(self._msg_text.format('; charset="unknown-8bit"'))
+        result = self._rule.check(self._mlist, msg, {})
+        self.assertTrue(result)
+        self.assertEqual(b'The above line will be removed!\n',
+                         msg.get_payload(0).get_payload(decode=True))
+        self.assertEqual(b'\n<div dir="ltr"><div></div><div>The password '
+                         b'approval will be removed!</div></div>\n',
+                         msg.get_payload(1).get_payload(decode=True))



View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/5b983bcfcaa6a22bd0d991ae80e6d3acd5b8c9d9...31f1ecd9542515a60a01aedcfa9d775a124a32eb

-- 
View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/5b983bcfcaa6a22bd0d991ae80e6d3acd5b8c9d9...31f1ecd9542515a60a01aedcfa9d775a124a32eb
You're receiving this email because of your account on gitlab.com.
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to