Skip to content

gh-145831: email.quoprimime: decode() leaves stray \r when eol='\r\n'#145832

Merged
bitdancer merged 6 commits intopython:mainfrom
stefanzetzsche:fix/email_quoprimime_crlf_stray_cr
Apr 9, 2026
Merged

gh-145831: email.quoprimime: decode() leaves stray \r when eol='\r\n'#145832
bitdancer merged 6 commits intopython:mainfrom
stefanzetzsche:fix/email_quoprimime_crlf_stray_cr

Conversation

@stefanzetzsche
Copy link
Copy Markdown
Contributor

@stefanzetzsche stefanzetzsche commented Mar 11, 2026

Issue

email.quoprimime.decode() does decoded[:-1] to strip a trailing line ending, but this only removes one character. When eol='\r\n' (2 characters), a stray \r is left in the output.

Reproducer

import email.quoprimime as qp
print(repr(qp.decode('abc', eol='\r\n')))  # 'abc\r' — expected 'abc'

Fix

In Lib/email/quoprimime.py, change:

decoded = decoded[:-1]

to:

decoded = decoded[:-len(eol)]

Tests

Three test cases added to TestQuopri in Lib/test/test_email/test_email.py:

  • test_decode_crlf_eol_no_trailing_newline — verifies decode('abc', eol='\r\n') returns 'abc' (direct reproducer for the bug; without the fix, returns 'abc\r').
  • test_decode_crlf_eol_multiline_no_trailing_newline — verifies decode('a\r\nb', eol='\r\n') returns 'a\r\nb' (multi-line input without trailing newline).
  • test_decode_crlf_eol_with_trailing_newline — verifies decode('abc\r\n', eol='\r\n') returns 'abc\r\n' (trailing newline is legitimate and should be preserved).

stefanzetzsche and others added 3 commits February 22, 2026 14:54
decoded[:-1] only strips one character, leaving a stray \r when eol
is two characters. Fix: decoded[:-len(eol)].
@stefanzetzsche stefanzetzsche marked this pull request as ready for review March 11, 2026 15:10
@stefanzetzsche stefanzetzsche requested a review from a team as a code owner March 11, 2026 15:10
@bitdancer bitdancer merged commit 1a0edb1 into python:main Apr 9, 2026
54 checks passed
@bitdancer bitdancer added awaiting merge needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes labels Apr 9, 2026
@miss-islington-app
Copy link
Copy Markdown

Thanks @stefanzetzsche for the PR, and @bitdancer for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

@miss-islington-app
Copy link
Copy Markdown

Thanks @stefanzetzsche for the PR, and @bitdancer for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Apr 9, 2026
…`eol='\r\n'` (pythonGH-145832)

decoded[:-1] only strips one character, leaving a stray \r when eol
is two characters. Fix: decoded[:-len(eol)].
(cherry picked from commit 1a0edb1)

Co-authored-by: Stefan Zetzsche <120379523+stefanzetzsche@users.noreply.github.com>
@bedevere-app
Copy link
Copy Markdown

bedevere-app bot commented Apr 9, 2026

GH-148311 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.13 bugs and security fixes label Apr 9, 2026
@bedevere-app
Copy link
Copy Markdown

bedevere-app bot commented Apr 9, 2026

GH-148312 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.14 bugs and security fixes label Apr 9, 2026
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Apr 9, 2026
…`eol='\r\n'` (pythonGH-145832)

decoded[:-1] only strips one character, leaving a stray \r when eol
is two characters. Fix: decoded[:-len(eol)].
(cherry picked from commit 1a0edb1)

Co-authored-by: Stefan Zetzsche <120379523+stefanzetzsche@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants