summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/docs/NEWS.rst4
-rw-r--r--src/mailman/rules/approved.py3
-rw-r--r--src/mailman/rules/tests/test_approved.py32
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)