[Checkins] SVN: Zope/branches/2.12/ Fixed possible TypeError while sending multipart emails.

Maurits van Rees m.van.rees at zestsoftware.nl
Mon Jan 4 22:51:56 EST 2010


Log message for revision 107689:
  Fixed possible TypeError while sending multipart emails.

Changed:
  U   Zope/branches/2.12/doc/CHANGES.rst
  U   Zope/branches/2.12/src/Products/MailHost/MailHost.py
  U   Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py

-=-
Modified: Zope/branches/2.12/doc/CHANGES.rst
===================================================================
--- Zope/branches/2.12/doc/CHANGES.rst	2010-01-05 03:22:30 UTC (rev 107688)
+++ Zope/branches/2.12/doc/CHANGES.rst	2010-01-05 03:51:55 UTC (rev 107689)
@@ -11,6 +11,8 @@
 Bugs Fixed
 ++++++++++
 
+- Fixed possible TypeError while sending multipart emails.
+
 - Also look for ZEXP imports within the clienthome directory. This
   provides a place to put imports that won't be clobbered by buildout
   in a buildout-based Zope instance.

Modified: Zope/branches/2.12/src/Products/MailHost/MailHost.py
===================================================================
--- Zope/branches/2.12/src/Products/MailHost/MailHost.py	2010-01-05 03:22:30 UTC (rev 107688)
+++ Zope/branches/2.12/src/Products/MailHost/MailHost.py	2010-01-05 03:51:55 UTC (rev 107689)
@@ -417,16 +417,31 @@
         # we don't use get_content_type because that has a default
         # value of 'text/plain'
         mo.set_type(msg_type)
-    charset_match = CHARSET_RE.search(mo['Content-Type'] or '')
-    if charset and not charset_match:
-        # Don't change the charset if already set
-        # This encodes the payload automatically based on the default
-        # encoding for the charset
-        mo.set_charset(charset)
-    elif charset_match and not charset:
-        # If a charset parameter was provided use it for header encoding below,
-        # Otherwise, try to use the charset provided in the message.
-        charset = charset_match.groups()[0]
+    if not mo.is_multipart():
+        charset_match = CHARSET_RE.search(mo['Content-Type'] or '')
+        if charset and not charset_match:
+            # Don't change the charset if already set
+            # This encodes the payload automatically based on the default
+            # encoding for the charset
+            mo.set_charset(charset)
+        elif charset_match and not charset:
+            # If a charset parameter was provided use it for header encoding below,
+            # Otherwise, try to use the charset provided in the message.
+            charset = charset_match.groups()[0]
+    else:
+        # Do basically the same for each payload as for the complete
+        # multipart message.
+        for index, payload in enumerate(mo.get_payload()):
+            if not isinstance(payload, Message):
+                payload = message_from_string(payload)
+            charset_match = CHARSET_RE.search(payload['Content-Type'] or '')
+            if payload.get_filename() is None:
+                # No binary file
+                if charset and not charset_match:
+                    payload.set_charset(charset)
+                elif charset_match and not charset:
+                    charset = charset_match.groups()[0]
+            mo.get_payload()[index] = payload
 
     # Parameters given will *always* override headers in the messageText.
     # This is so that you can't override or add to subscribers by adding

Modified: Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py
===================================================================
--- Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py	2010-01-05 03:22:30 UTC (rev 107688)
+++ Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py	2010-01-05 03:51:55 UTC (rev 107689)
@@ -518,7 +518,93 @@
                                        statusTemplate='check_status')
         self.failUnlessEqual(result, 'Message Sent')
 
+    def testSendMultiPartAlternativeMessage(self):
+        msg = ("""\
+Content-Type: multipart/alternative; boundary="===============0490954888=="
+MIME-Version: 1.0
+Date: Sun, 27 Aug 2006 17:00:00 +0200
+Subject: My multipart email
+To: Foo Bar <foo at domain.com>
+From: sender at domain.com
 
+--===============0490954888==
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: quoted-printable
+
+This is plain text.
+--===============0490954888==
+Content-Type: text/html; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: quoted-printable
+
+<p>This is html.</p>
+--===============0490954888==--
+""")
+
+        mailhost = self._makeOne('MailHost')
+        # Specifying a charset for the header may have unwanted side
+        # effects in the case of multipart mails.
+        # (TypeError: expected string or buffer)
+        mailhost.send(msg, charset='utf-8')
+        self.assertEqual(mailhost.sent, msg)
+
+    def testSendMultiPartMixedMessage(self):
+        msg = ("""\
+Content-Type: multipart/mixed; boundary="XOIedfhf+7KOe/yw"
+Content-Disposition: inline
+MIME-Version: 1.0
+Date: Sun, 27 Aug 2006 17:00:00 +0200
+Subject: My multipart email
+To: Foo Bar <foo at domain.com>
+From: sender at domain.com
+
+--XOIedfhf+7KOe/yw
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+This is a test with as attachment OFS/www/new.gif.
+
+--XOIedfhf+7KOe/yw
+Content-Type: image/gif
+Content-Disposition: attachment; filename="new.gif"
+Content-Transfer-Encoding: base64
+
+R0lGODlhCwAQAPcAAP8A/wAAAFBQUICAgMDAwP8AAIAAQAAAoABAgIAAgEAAQP//AP//gACA
+gECAgP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAALABAAAAg7AAEIFKhgoEGC
+CwoeRKhwoYKEBhVIfLgg4UQAFCtqbJixYkOEHg9SHDmQJEmMEBkS/IiR5cKXMGPKDAgAOw==
+
+--XOIedfhf+7KOe/yw
+Content-Type: text/plain; charset=iso-8859-1
+Content-Disposition: attachment; filename="test.txt"
+Content-Transfer-Encoding: quoted-printable
+
+D=EDt =EFs =E9=E9n test
+
+--XOIedfhf+7KOe/yw--
+""")
+
+        mailhost = self._makeOne('MailHost')
+        # Specifying a charset for the header may have unwanted side
+        # effects in the case of multipart mails.
+        # (TypeError: expected string or buffer)
+        mailhost.send(msg, charset='utf-8')
+        self.assertEqual(mailhost.sent, msg)
+
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest( unittest.makeSuite( TestMailHost ) )



More information about the checkins mailing list