email ContentManager mutates messages after failed content validation and accepts unknown byte CTE values

オープン
#157,254 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
python
領域
backend

調査の方向性

email.message.EmailMessage.set_content() と add_attachment() のエントリーポイントから始め、その後、再現コードで使用されているテキストおよび bytes のコンテンツハンドラーをたどります。提供された例と関連する email テストを実行します。失敗したコンテンツ要求によって以前にシリアライズされたメッセージが保持され、サポートされていない bytes の CTE 値が拒否されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

stdlib topic-email type-bug

Bug report

Summary

EmailMessage.set_content() clears existing content before built-in content validation completes. A failing text-content request therefore destroys the original payload. Separately, the bytes content handler accepts arbitrary cte strings and serializes them as Content-Transfer-Encoding, even though the documented API defines a fixed set of permitted values. Together, these behaviors let invalid content requests corrupt an existing message or produce invalid outgoing MIME metadata.

Reproduction Code
from email.message import EmailMessage

# Failed text setup loses the prior message content.
msg = EmailMessage()
msg.set_content("original")
before = msg.as_bytes()
try:
    msg.set_content("replacement", charset="does-not-exist")
except LookupError as exc:
    print(type(exc).__name__, exc)
print(msg.as_bytes() == before)
print(msg.as_string())

# Unsupported byte CTE is accepted and emitted unchanged.
msg = EmailMessage()
msg.set_content(
    b"abc",
    maintype="application",
    subtype="octet-stream",
    cte="not-a-transfer-encoding",
)
print(msg.as_bytes().decode("ascii"))
Actual Behavior

The first request raises LookupError: unknown encoding: does-not-exist, then prints False. The serialized message no longer contains original; it retains MIME headers added before the failure.

The second request succeeds and produces:

Content-Type: application/octet-stream
Content-Transfer-Encoding: not-a-transfer-encoding
MIME-Version: 1.0

abc

A failing add_attachment("replacement", charset="does-not-exist") also leaves the parent converted to a one-part multipart/mixed message.

Expected Behavior

Invalid content requests should raise before changing the target message. In particular, a failed set_content() or add_attachment() call should preserve the prior serialized message and MIME structure.

The bytes content handler should reject unsupported CTE values with ValueError, consistently with the documented CTE set and the text content handler, rather than emitting an unrecognized Content-Transfer-Encoding header.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-157263
主要言語
Python
スター
77.2k
フォーク
36k
平均マージ
1日 9時間
マージ済み PR(30日)
558

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

python/cpython のほかの issue

python/cpython の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。