Permalink
Browse files

In Python 2.7, encode strings in add_header() as ASCII (#72)

* In Python 2, encode other strings in add_header() calls into ASCII so getting this filename does not cause Unicode errors
* Fix test compatibility in Python3
1 parent aa415c3 commit 3995ef98a3f7feb75f1aeb652e6afe40a5c94def @stevenbuccini stevenbuccini committed with amcgregor Dec 3, 2016
Showing with 33 additions and 3 deletions.
  1. +10 −3 marrow/mailer/message.py
  2. +23 −0 test/test_message.py
View
@@ -322,11 +322,18 @@ def attach(self, name, data=None, maintype=None, subtype=None,
filename=(filename_charset, filename_language, filename)
if inline:
- part.add_header('Content-Disposition', 'inline', filename=filename)
- part.add_header('Content-ID', '<%s>' % filename)
+ if sys.version_info < (3, 0):
+ part.add_header('Content-Disposition'.encode('utf-8'), 'inline'.encode('utf-8'), filename=filename)
+ part.add_header('Content-ID'.encode('utf-8'), '<%s>'.encode('utf-8') % filename)
+ else:
+ part.add_header('Content-Disposition', 'inline', filename=filename)
+ part.add_header('Content-ID', '<%s>' % filename)
self.embedded.append(part)
else:
- part.add_header('Content-Disposition', 'attachment', filename=filename)
+ if sys.version_info < (3, 0):
+ part.add_header('Content-Disposition'.encode('utf-8'), 'attachment'.encode('utf-8'), filename=filename)
+ else:
+ part.add_header('Content-Disposition', 'attachment', filename=filename)
self.attachments.append(part)
def embed(self, name, data=None):
View
@@ -281,6 +281,29 @@ def test_mime_embed_failures(self):
with pytest.raises(TypeError):
message.embed('test.gif', object())
+
+ def test_that_add_header_and_collapse_header_are_inverses_ascii_filename(self):
+ message = self.build_message()
+ message.plain = "Hello world."
+ message.rich = "Farewell cruel world."
+ message.attach("wat.txt", b"not a unicode snowman") # calls add_header() under the covers
+ attachment = message.attachments[0]
+ filename = attachment.get_filename() # calls email.utils.collapse_rfc2231_value() under the covers
+ assert filename == "wat.txt"
+
+ def test_that_add_header_and_collapse_header_are_inverses_non_ascii_filename(self):
+ message = self.build_message()
+ message.plain = "Hello world."
+ message.rich = "Farewell cruel world."
+ message.attach("☃.txt", b"unicode snowman", filename_language='en-us')
+ attachment = message.attachments[0]
+ filename = attachment.get_param('filename', object(), 'content-disposition') # get_filename() calls this under the covers
+ assert isinstance(filename, tuple) # Since attachment encoded according to RFC2231, should be represented as a tuple
+ filename = attachment.get_filename() # Calls email.utils.collapse_rfc2231_value() under the covers, currently fails
+ if sys.version_info < (3, 0):
+ assert isinstance(filename, basestring) # Successfully converts tuple to a string
+ else:
+ assert isinstance(filename, str)
def test_recipients_collection(self):
message = self.build_message()

0 comments on commit 3995ef9

Please sign in to comment.