Skip to content

gh-62222: Fix and extend quoted-printable decoding - #152679

Open
serhiy-storchaka wants to merge 2 commits into
python:mainfrom
serhiy-storchaka:gh-62222-qp-malformed-escape
Open

gh-62222: Fix and extend quoted-printable decoding#152679
serhiy-storchaka wants to merge 2 commits into
python:mainfrom
serhiy-storchaka:gh-62222-qp-malformed-escape

Conversation

@serhiy-storchaka

Copy link
Copy Markdown
Member

binascii.a2b_qp() and quopri now leave an invalid = escape (one not followed by two hexadecimal digits or a soft line break) in place and rescan the following character instead of consuming it, like email.quoprimime and other quoted-printable decoders. For example b'==41' now decodes to b'=A' instead of b'=41'.

A new opt-in strip_ws parameter is added to binascii.a2b_qp(), quopri.decode(), quopri.decodestring() and email.quoprimime.decode(). When true, whitespace at the end of each line is stripped while decoding, as required by RFC 2045 for a quoted-printable body, while encoded whitespace (=20/=09) is preserved. It is false by default everywhere except email.quoprimime.decode(), so every existing default is preserved.

The documentation for email.message.Message.get_payload(decode=True) now notes that it does not strip trailing whitespace from a quoted-printable body, contrary to RFC 2045 — this matches the behavior of common mail clients.

binascii.a2b_qp() and quopri now leave an invalid "=" escape in place and
rescan the following character instead of consuming it, like email.quoprimime
and other decoders (b'==41' now decodes to b'=A').
Add an opt-in strip_ws parameter to binascii.a2b_qp(), quopri.decode(),
quopri.decodestring() and email.quoprimime.decode() to strip trailing
whitespace per RFC 2045. It is false by default everywhere except
email.quoprimime.decode(), preserving every existing default.
Also document that email's get_payload(decode=True) does not strip trailing
whitespace, contrary to RFC 2045.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@read-the-docs-community

read-the-docs-communityBot commented Jun 30, 2026

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33373283 | 📁 Comparing df866a9 against main (ecdef17)

🔍 Preview build

5 files changed · ± 5 modified

±Modified

Register the new "strip_ws" argument name in the global objects tables
(make regen-global-objects), needed by static builds where binascii is
compiled into the core, and replace an unresolved :func: reference to the
undocumented email.quoprimime.decode with a literal.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@serhiy-storchaka