Skip to content

Commit 19da6df

Browse files
committed
Fixed a bug where emails with multipart/related content did not round-trip correctly through email.parser.parsebytes() and as_bytes().
1 parent 800d37f commit 19da6df

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

Lib/email/generator.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,11 @@ class BytesGenerator(Generator):
417417
"""
418418

419419
def write(self, s):
420-
self._fp.write(s.encode('ascii', 'surrogateescape'))
420+
if getattr(self.policy, "utf8", False):
421+
encoded = s.encode('utf-8', 'surrogateescape')
422+
else:
423+
encoded = s.encode('ascii', 'surrogateescape')
424+
self._fp.write(encoded)
421425

422426
def _new_buffer(self):
423427
return BytesIO()

Lib/test/test_email/test_generator.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,20 @@ def test_smtp_policy(self):
471471
g = BytesGenerator(s, policy=policy.SMTP)
472472
g.flatten(msg)
473473
self.assertEqual(s.getvalue(), expected)
474+
def test_utf8_round_trip_preserves_unicode_body(self):
475+
msg = EmailMessage()
476+
msg['From'] = "Páolo <fő[email protected]>"
477+
msg['To'] = 'Dinsdale'
478+
msg['Subject'] = 'Nudge nudge, wink, wink \u1F609'
479+
msg.set_content("oh là là, know what I mean, know what I mean?")
480+
s = io.BytesIO()
481+
g = BytesGenerator(s, policy=policy.SMTPUTF8)
482+
g.flatten(msg)
483+
out = s.getvalue()
484+
parsed = message_from_bytes(out, policy=policy.default.clone(utf8=True))
485+
486+
self.assertEqual(parsed["Subject"], 'Nudge nudge, wink, wink \u1F609')
487+
self.assertEqual(parsed.get_body().get_content(), "oh là là, know what I mean, know what I mean?\r\n")
474488

475489

476490
if __name__ == '__main__':
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a bug where emails with `multipart/related` content did not round-trip
2+
correctly through `email.parser.parsebytes()` and `as_bytes()`.

0 commit comments

Comments
 (0)