Skip to content

gh-43702: Replace existing Content-Transfer-Encoding in encode_base64() and encode_quopri() - #158230

Open
soreavis wants to merge 1 commit into
python:mainfrom
soreavis:gh-43702-encoders-replace-cte
Open

soreavis wants to merge 1 commit into
python:mainfrom
soreavis:gh-43702-encoders-replace-cte

Conversation

@soreavis

@soreavis soreavis commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

encode_base64() and encode_quopri() add a Content-Transfer-Encoding header without removing an existing one. Re-encoding a message that already has one, such as a utf-8 MIMEText, leaves two headers, and get_payload(decode=True) then decodes the body with the old one:

from email import encoders
from email.mime.text import MIMEText

msg = MIMEText('héllo', _charset='utf-8')  # Content-Transfer-Encoding: base64
encoders.encode_quopri(msg)
msg.get_all('Content-Transfer-Encoding')   # ['base64', 'quoted-printable']
msg.get_payload(decode=True)               # b'\x84-\xc0\xf6Yh'

The double-encoded payload was fixed in 2013 by gh-62524 (bpo-18324), which made the encoders decode the payload first. In 2021 the reporter confirmed the duplicate header was still there. R. David Murray had said the encoders' behavior on an already encoded message could be fixed, "since it is unlikely that anyone would be depending on such behavior". Both functions rewrite the payload, so the old header can be deleted before the new one is set. With email.policy.default, which allows only one such header, they used to raise ValueError here and now work.

encode_7or8bit() is left alone, although I listed it on the issue. It doesn't touch the payload, so on a base64 or quoted-printable body the old header is the one that still describes it. Replacing it would mislabel the body.

#43702

…opri()

Both encoders added a Content-Transfer-Encoding header without removing
an existing one, so re-encoding a message that already had one left two
such headers.  Delete the old header first.  encode_7or8bit() is left
alone because it does not change the payload.
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.

1 participant