From 46be53f14a5ce8737f0974b568af83be63959478 Mon Sep 17 00:00:00 2001 From: skv0zsneg Date: Sat, 28 Jun 2025 13:58:54 +0300 Subject: [PATCH 1/7] Fix UnboundLocalError for bytes payload and quoted-printable cte. --- Lib/email/message.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/email/message.py b/Lib/email/message.py index 41fcc2b9778798..464b23de7bcf1c 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -313,6 +313,8 @@ def get_payload(self, i=None, decode=False): # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') + elif isinstance(payload, bytes): + bpayload = payload if cte == 'quoted-printable': return quopri.decodestring(bpayload) elif cte == 'base64': From 2d2906d8704174a39596bd53f1093704c9cf8fbe Mon Sep 17 00:00:00 2001 From: skv0zsneg Date: Sat, 28 Jun 2025 13:59:26 +0300 Subject: [PATCH 2/7] Add test for getting bytes payload with quoted-printable cte. --- Lib/test/test_email/test_message.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index 23c39775a8b2e5..9817f56efeedc3 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -1055,6 +1055,13 @@ def test_get_body_malformed(self): # AttributeError: 'str' object has no attribute 'is_attachment' m.get_body() + def test_get_bytes_payload_with_quoted_printable_encoding(self): + payload = b'Some payload' + m = self._make_message() + m.add_header('Content-Transfer-Encoding', 'quoted-printable') + m._payload = payload + self.assertEqual(m.get_payload(decode=True), payload) + class TestMIMEPart(TestEmailMessageBase, TestEmailBase): # Doing the full test run here may seem a bit redundant, since the two From 8ccd326cc490da95361099c552994881ded5ba85 Mon Sep 17 00:00:00 2001 From: skv0zsneg Date: Sat, 28 Jun 2025 14:13:22 +0300 Subject: [PATCH 3/7] Add myself to ACKS list. --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index 6ab50763feadd9..043d4927e8eb10 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1054,6 +1054,7 @@ Alexander Lakeev David Lam Thomas Lamb Valerie Lambert +Kliment Lamonov Peter Lamut Jean-Baptiste "Jiba" Lamy Ronan Lamy From 2271433af466629a5e8638f611934b1000d1650f Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 28 Jun 2025 11:32:58 +0000 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst diff --git a/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst b/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst new file mode 100644 index 00000000000000..1d94f09df2f8ea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst @@ -0,0 +1 @@ +Fix ``UnboundLocalError`` in ``email.message.Message.get_payload``. Patch by Kliment Lamonov. From e156408819d0ad3efe0e86409da8cb210ce37d63 Mon Sep 17 00:00:00 2001 From: skv0zsneg Date: Sat, 28 Jun 2025 14:38:56 +0300 Subject: [PATCH 5/7] Change elif statement to if --- Lib/email/message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/email/message.py b/Lib/email/message.py index 464b23de7bcf1c..36e4b4a9f0b773 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -313,7 +313,7 @@ def get_payload(self, i=None, decode=False): # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') - elif isinstance(payload, bytes): + else: bpayload = payload if cte == 'quoted-printable': return quopri.decodestring(bpayload) From 125a69a1d4b9079cb650ad8d08912d51587dc858 Mon Sep 17 00:00:00 2001 From: Kliment Lamonov Date: Sat, 28 Jun 2025 14:40:47 +0300 Subject: [PATCH 6/7] Update Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- .../Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst b/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst index 1d94f09df2f8ea..79b85320926954 100644 --- a/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst +++ b/Misc/NEWS.d/next/Library/2025-06-28-11-32-57.gh-issue-134759.AjjKcG.rst @@ -1 +1,2 @@ -Fix ``UnboundLocalError`` in ``email.message.Message.get_payload``. Patch by Kliment Lamonov. +Fix :exc:`UnboundLocalError` in :func:`email.message.Message.get_payload` when +the payload to decode is a :class:`bytes` object. Patch by Kliment Lamonov. From af9dae0dbef10e9c7e9a10d42d0d7bdcf59a8fc7 Mon Sep 17 00:00:00 2001 From: skv0zsneg Date: Sun, 29 Jun 2025 15:22:54 +0300 Subject: [PATCH 7/7] Upd test for using public method. --- Lib/test/test_email/test_message.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index 9817f56efeedc3..c116a7011f60d3 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -1056,10 +1056,10 @@ def test_get_body_malformed(self): m.get_body() def test_get_bytes_payload_with_quoted_printable_encoding(self): - payload = b'Some payload' + payload = memoryview(b'Some payload') m = self._make_message() m.add_header('Content-Transfer-Encoding', 'quoted-printable') - m._payload = payload + m.set_payload(payload) self.assertEqual(m.get_payload(decode=True), payload)