From 00bc8b51499ebc6dd378865415ab37fa687edfe3 Mon Sep 17 00:00:00 2001 From: Tan Long Date: Tue, 24 Jun 2025 08:24:54 +0800 Subject: [PATCH 1/4] Fix email.parser stripping boudaries twice --- Lib/email/message.py | 2 +- Lib/test/test_email/test_email.py | 36 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Lib/email/message.py b/Lib/email/message.py index 41fcc2b9778798..90b135409f5c7e 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -862,7 +862,7 @@ def get_boundary(self, failobj=None): parameter, and it is unquoted. """ missing = object() - boundary = self.get_param('boundary', missing) + boundary = self.get_param('boundary', missing, unquote=False) if boundary is missing: return failobj # RFC 2046 says that boundaries may begin but not end in w/s diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index b8116d073a2670..b572d495fcd28f 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -2209,6 +2209,42 @@ def test_boundary_with_leading_space(self): eq(msg.get_boundary(), ' XXXX') eq(len(msg.get_payload()), 2) + def test_boundary_stripped_only_once(self): + eq = self.assertEqual + msg = email.message_from_string('''\ +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="<>" + +--<> +Content-Type: text/plain + + +--<> +Content-Type: text/plain + +--<>-- +''') + self.assertTrue(msg.is_multipart()) + eq(msg.get_boundary(), '<>') + eq(len(msg.get_payload()), 2) + + msg = email.message_from_string('''\ +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary=<""> + +--"" +Content-Type: text/plain + + +--"" +Content-Type: text/plain + +--""-- +''') + self.assertTrue(msg.is_multipart()) + eq(msg.get_boundary(), '""') + eq(len(msg.get_payload()), 2) + def test_boundary_without_trailing_newline(self): m = Parser().parsestr("""\ Content-Type: multipart/mixed; boundary="===============0012394164==" From d3c93ea09c49e88bc23af9f57d8fb843431bf00b Mon Sep 17 00:00:00 2001 From: Tan Long Date: Tue, 24 Jun 2025 21:08:32 +0800 Subject: [PATCH 2/4] blurb add --- .../next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst diff --git a/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst b/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst new file mode 100644 index 00000000000000..15b6a9b741a1a8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst @@ -0,0 +1 @@ +Fix :class:`email.parser` strips boundaries twice. From e9cfcc9ffeea3ae36df6e7c4bcbbba2061684996 Mon Sep 17 00:00:00 2001 From: Tan Long Date: Tue, 24 Jun 2025 21:08:32 +0800 Subject: [PATCH 3/4] improve news entry --- .../next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst b/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst index 15b6a9b741a1a8..95f3ced404c8b1 100644 --- a/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst +++ b/Misc/NEWS.d/next/Library/2025-06-24-21-08-26.gh-issue-135854.j0WMfD.rst @@ -1 +1 @@ -Fix :class:`email.parser` strips boundaries twice. +Fix :func:`email.message.Message.get_boundary` strips boundaries twice. From 7f410eb6c3c09d8f0d2003e8d8c939443ae1de81 Mon Sep 17 00:00:00 2001 From: Tan Long Date: Wed, 25 Jun 2025 16:45:55 +0800 Subject: [PATCH 4/4] indent multiline string --- Lib/test/test_email/test_email.py | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index b572d495fcd28f..978a35abbb63ad 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -2211,36 +2211,36 @@ def test_boundary_with_leading_space(self): def test_boundary_stripped_only_once(self): eq = self.assertEqual - msg = email.message_from_string('''\ -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="<>" + msg = email.message_from_string(textwrap.dedent('''\ + MIME-Version: 1.0 + Content-Type: multipart/mixed; boundary="<>" ---<> -Content-Type: text/plain + --<> + Content-Type: text/plain ---<> -Content-Type: text/plain + --<> + Content-Type: text/plain ---<>-- -''') + --<>-- + ''')) self.assertTrue(msg.is_multipart()) eq(msg.get_boundary(), '<>') eq(len(msg.get_payload()), 2) - msg = email.message_from_string('''\ -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary=<""> + msg = email.message_from_string(textwrap.dedent('''\ + MIME-Version: 1.0 + Content-Type: multipart/mixed; boundary=<""> ---"" -Content-Type: text/plain + --"" + Content-Type: text/plain ---"" -Content-Type: text/plain + --"" + Content-Type: text/plain ---""-- -''') + --""-- + ''')) self.assertTrue(msg.is_multipart()) eq(msg.get_boundary(), '""') eq(len(msg.get_payload()), 2)