diff options
| -rw-r--r-- | src/mailman/docs/NEWS.rst | 4 | ||||
| -rw-r--r-- | src/mailman/rules/approved.py | 3 | ||||
| -rw-r--r-- | src/mailman/rules/tests/test_approved.py | 32 |
3 files changed, 37 insertions, 2 deletions
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index ac81cd386..0a4b2fb51 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -16,9 +16,11 @@ Bugs ---- * Fixed Unicode errors in the digest runner and when sending messages to the site owner as a fallback. Given by Aurélien Bompard. (LP: #1130957). - * Fix Unicode errors when a message being added to the digest has non-ascii + * Fixed Unicode errors when a message being added to the digest has non-ascii characters in its payload, but no Content-Type header defining a charset. Given by Aurélien Bompard. (LP: #1170347) + * Fixed messages without a `text/plain` part crashing the `Approved` rule. + Given by Aurélien Bompard. (LP: #1158721) Commands -------- diff --git a/src/mailman/rules/approved.py b/src/mailman/rules/approved.py index 2839ffef4..3b40d5dc9 100644 --- a/src/mailman/rules/approved.py +++ b/src/mailman/rules/approved.py @@ -71,9 +71,10 @@ class Approved: # Find the first text/plain part in the message part = None stripped = False + payload = None for part in typed_subpart_iterator(msg, 'text', 'plain'): + payload = part.get_payload(decode=True) break - payload = part.get_payload(decode=True) if payload is not None: charset = part.get_content_charset('us-ascii') payload = payload.decode(charset, 'replace') diff --git a/src/mailman/rules/tests/test_approved.py b/src/mailman/rules/tests/test_approved.py index e7f122410..9976d4eff 100644 --- a/src/mailman/rules/tests/test_approved.py +++ b/src/mailman/rules/tests/test_approved.py @@ -491,3 +491,35 @@ deprecated = roundup_plaintext self.assertFalse(result) self.assertEqual(self._mlist.moderator_password, b'{plaintext}super secret') + + +class TestApprovedNoTextPlainPart(unittest.TestCase): + """Test the approved handler with HTML-only messages.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + self._rule = approved.Approved() + + def test_no_text_plain_part(self): + # When the message body only contains HTML, the rule should not throw + # AttributeError: 'NoneType' object has no attribute 'get_payload' + # LP: #1158721 + msg = mfs("""\ +From: anne@example.com +To: test@example.com +Subject: HTML only email +Message-ID: <ant> +MIME-Version: 1.0 +Content-Type: text/html; charset="Windows-1251" +Content-Transfer-Encoding: 7bit + +<HTML> +<BODY> +<P>This message contains only HTML, no plain/text part</P> +</BODY> +</HTML> +""") + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) |
