Skip to content

gh-99927: Preserve UTF-8 headers under the SMTPUTF8 email policy - #159508

Open
charan-rathore wants to merge 2 commits into
python:mainfrom
charan-rathore:gh-99927-smtputf8-policy
Open

charan-rathore wants to merge 2 commits into
python:mainfrom
charan-rathore:gh-99927-smtputf8-policy

Conversation

@charan-rathore

@charan-rathore charan-rathore commented Oct 16, 2026 •

Copy link
Copy Markdown

When a message is parsed from bytes with policy=SMTPUTF8 and then flattened back to bytes, UTF-8 header values got mangled and the body could be demoted to unknown-8bit.

header_source_parse now round-trips the parsed header value through UTF-8 (with surrogateescape) when the policy has utf8 enabled, so a parse/flatten round trip is stable.

Adds regression tests covering the UTF-8 round trip and invalid header bytes.

Signed-off-by: Charan Rathore <180254320+charan-rathore@users.noreply.github.com>
@charan-rathore
charan-rathore requested a review from a team as a code owner October 16, 2026 03:57
@python-cla-bot

Copy link
Copy Markdown

The following commit authors need to sign the Contributor License Agreement:

CLA not signed

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-16T04:06:22.243723Z 4966a32 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4966a32a52

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Lib/email/policy.py Outdated
Comment on lines +137 to +138
value = value.encode('utf-8', 'surrogateescape').decode(
'utf-8', 'surrogateescape')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve address structure when switching to compat32

When a bytes message parsed with SMTPUTF8 is later serialized with policy=compat32 (the supported policy-switching flow described just above this method), this decoding changes a raw address from surrogateescaped bytes to an ordinary str. msg.as_bytes(policy=compat32) then passes To: Jörg <a@b> through Compat32's unstructured Header and emits To: =?utf-8?b?SsO2cmcgPGFAYj4=?=; reparsing that produces an invalid addr-spec instead of recipient a@b because the structural delimiters were encoded too. Before this change the default 8-bit fold_binary path preserved the structured raw bytes, so the UTF-8 conversion needs to be deferred to the SMTPUTF8-specific fold/fetch path or otherwise retain structure across the advertised policy switch.

Useful? React with 👍 / 👎.

Decoding surrogateescaped header bytes at parse time changed the value
seen by every downstream policy: serializing an SMTPUTF8-parsed message
with policy=compat32 then encoded-worded whole address headers and
destroyed the addr-spec. Perform the conversion only when a utf8 policy
actually refolds a source value, preserving structure under compat32.

Adds a regression test for the SMTPUTF8-parse/compat32-serialize flow.

Signed-off-by: Charan Rathore <180254320+charan-rathore@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.

1 participant