File bpo27321-email-no-replace-header.patch of Package python3.36158
From 3c864b72138be6a559e36772246215aaef504a11 Mon Sep 17 00:00:00 2001
From: Mark Sapiro <mark@msapiro.net>
Date: Mon, 19 Oct 2020 16:11:37 -0700
Subject: [PATCH] fix email.generator.py to not replace a non-existent header
This PR replaces GH-1977. The reason for the replacement is
two-fold.
The fix itself is different is that if the CTE header doesn't
exist in the original message, it is inserted. This is important
because the new CTE could be quoted-printable whereas the
original is implicit 8bit.
Also the tests are different. The
test_nonascii_as_string_without_cte test in gh-1977 doesn't
actually test the issue in that it passes without the fix. The
test_nonascii_as_string_without_content_type_and_cte test is
improved here, and even though it doesn't fail without the fix,
it is included for completeness.
Fixed KeyError exception when flattening an email to a string
attempts to replace a non-existent Content-Transfer-Encoding
header.
Code is originally from gh#python/cpython@371146a3f8, it was
released upstream in 3.8.7
Co-authored-by: Mark Sapiro <mark@msapiro.net>
Date: Mon, 19 Oct 2020 16:11:37 -0700
Fixes: bsc#1208443
Patch: bpo27321-email-no-replace-header.patch
---
Lib/email/generator.py | 6 +++-
Lib/test/test_email/test_email.py | 35 +++++++++++++++++++
.../2020-01-19-18-40-26.bpo-27321.8e6SpM.rst | 2 ++
3 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 Misc/NEWS.d/next/Library/2020-01-19-18-40-26.bpo-27321.8e6SpM.rst
diff --git a/Lib/email/generator.py b/Lib/email/generator.py
index ae670c2353c..c9b121624e0 100644
--- a/Lib/email/generator.py
+++ b/Lib/email/generator.py
@@ -186,7 +186,11 @@ class Generator:
# If we munged the cte, copy the message again and re-fix the CTE.
if munge_cte:
msg = deepcopy(msg)
- msg.replace_header('content-transfer-encoding', munge_cte[0])
+ # Preserve the header order if the CTE header already exists.
+ if msg.get('content-transfer-encoding') is None:
+ msg['Content-Transfer-Encoding'] = munge_cte[0]
+ else:
+ msg.replace_header('content-transfer-encoding', munge_cte[0])
msg.replace_header('content-type', munge_cte[1])
# Write the headers. First we see if the message object wants to
# handle that itself. If not, we'll do it generically.
diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py
index e4e40b612fe..fc0b8a0d9ba 100644
--- a/Lib/test/test_email/test_email.py
+++ b/Lib/test/test_email/test_email.py
@@ -314,6 +314,41 @@ class TestMessageAPI(TestEmailBase):
g.flatten(msg)
self.assertEqual(fullrepr, s.getvalue())
+ def test_nonascii_as_string_without_cte(self):
+ m = textwrap.dedent("""\
+ MIME-Version: 1.0
+ Content-type: text/plain; charset="iso-8859-1"
+
+ Test if non-ascii messages with no Content-Transfer-Encoding set
+ can be as_string'd:
+ Föö bär
+ """)
+ source = m.encode('iso-8859-1')
+ expected = textwrap.dedent("""\
+ MIME-Version: 1.0
+ Content-type: text/plain; charset="iso-8859-1"
+ Content-Transfer-Encoding: quoted-printable
+
+ Test if non-ascii messages with no Content-Transfer-Encoding set
+ can be as_string'd:
+ F=F6=F6 b=E4r
+ """)
+ msg = email.message_from_bytes(source)
+ self.assertEqual(msg.as_string(), expected)
+
+ def test_nonascii_as_string_without_content_type_and_cte(self):
+ m = textwrap.dedent("""\
+ MIME-Version: 1.0
+
+ Test if non-ascii messages with no Content-Type nor
+ Content-Transfer-Encoding set can be as_string'd:
+ Föö bär
+ """)
+ source = m.encode('iso-8859-1')
+ expected = source.decode('ascii', 'replace')
+ msg = email.message_from_bytes(source)
+ self.assertEqual(msg.as_string(), expected)
+
def test_as_bytes(self):
msg = self._msgobj('msg_01.txt')
with openfile('msg_01.txt') as fp:
diff --git a/Misc/NEWS.d/next/Library/2020-01-19-18-40-26.bpo-27321.8e6SpM.rst b/Misc/NEWS.d/next/Library/2020-01-19-18-40-26.bpo-27321.8e6SpM.rst
new file mode 100644
index 00000000000..28acf7f6ef9
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-01-19-18-40-26.bpo-27321.8e6SpM.rst
@@ -0,0 +1,2 @@
+Fixed KeyError exception when flattening an email to a string attempts to
+replace a non-existent Content-Transfer-Encoding header.
--
2.45.0