From 8b25c0ec441cfa0095f9c98aa68e5c27e49a7464 Mon Sep 17 00:00:00 2001 From: Stefan Zetzsche Date: Sun, 22 Feb 2026 14:54:08 +0000 Subject: [PATCH 1/4] gh-XXXXX: Fix email.quoprimime.decode() stray CR with eol='\r\n' decoded[:-1] only strips one character, leaving a stray \r when eol is two characters. Fix: decoded[:-len(eol)]. --- Lib/email/quoprimime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/email/quoprimime.py b/Lib/email/quoprimime.py index 27c7ea55c7871f..bc53b376821310 100644 --- a/Lib/email/quoprimime.py +++ b/Lib/email/quoprimime.py @@ -272,7 +272,7 @@ def decode(encoded, eol=NL): decoded += eol # Special case if original string did not end with eol if encoded[-1] not in '\r\n' and decoded.endswith(eol): - decoded = decoded[:-1] + decoded = decoded[:-len(eol)] return decoded From 948421f95d2bf656bf4a34ccc47f16ffec2da5e2 Mon Sep 17 00:00:00 2001 From: Stefan Zetzsche Date: Wed, 11 Mar 2026 14:59:39 +0000 Subject: [PATCH 2/4] Add tests for quoprimime.decode() with eol=CRLF --- Lib/test/test_email/test_email.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 4e6c213510c74c..e496d263e41367 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -4828,6 +4828,17 @@ def test_decode_soft_line_break(self): def test_decode_false_quoting(self): self._test_decode('A=1,B=A ==> A+B==2', 'A=1,B=A ==> A+B==2') + def test_decode_crlf_eol_no_trailing_newline(self): + # decode() with eol='\r\n' should not leave a stray \r + # when the input has no trailing line ending. + self._test_decode('abc', 'abc', eol='\r\n') + + def test_decode_crlf_eol_multiline_no_trailing_newline(self): + self._test_decode('a\r\nb', 'a\r\nb', eol='\r\n') + + def test_decode_crlf_eol_with_trailing_newline(self): + self._test_decode('abc\r\n', 'abc\r\n', eol='\r\n') + def _test_encode(self, body, expected_encoded_body, maxlinelen=None, eol=None): kwargs = {} if maxlinelen is None: From d559797adb79c310e9e83fc1de13ef0ce51a3c46 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:09:53 +0000 Subject: [PATCH 3/4] =?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/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst diff --git a/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst b/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst new file mode 100644 index 00000000000000..900cb04ada30d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst @@ -0,0 +1,2 @@ +Fix :func:`email.quoprimime.decode` leaving a stray ``\r`` when +``eol='\r\n'`` by stripping the full *eol* string instead of one character. From 8e99df599b31441d22294023aa0717ef0b4eb106 Mon Sep 17 00:00:00 2001 From: Stefan Zetzsche Date: Wed, 11 Mar 2026 15:53:52 +0000 Subject: [PATCH 4/4] Fix NEWS entry: suppress Sphinx cross-reference for undocumented email.quoprimime.decode --- .../next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst b/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst index 900cb04ada30d2..454b62bc0db95f 100644 --- a/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst +++ b/Misc/NEWS.d/next/Library/2026-03-11-15-09-52.gh-issue-145831._sW94w.rst @@ -1,2 +1,2 @@ -Fix :func:`email.quoprimime.decode` leaving a stray ``\r`` when +Fix :func:`!email.quoprimime.decode` leaving a stray ``\r`` when ``eol='\r\n'`` by stripping the full *eol* string instead of one character.