email: uncaught IndexError in the header parser on empty-input edge cases
還沒有人認領這個 Issue。
評估
研究方向
先在 email.policy.default 下重現兩個 message_from_string 範例,然後檢查 email._header_value_parser 中的 get_parameter 和 DisplayName.display_name。將它們的空輸入路徑與現有的 HeaderParseError 和缺陷復原行為進行比較。完成標準是,格式錯誤的參數和位址標頭不再以 IndexError 的形式逸出;gh-151858 已作為修正 PR 連結。
由索引模型根據 Issue 內容生成。
描述
The modern email header parser (email._header_value_parser, used under EmailPolicy / email.policy.default) raises a bare IndexError instead of a HeaderParseError / defect on two malformed inputs. The shared root cause is the same bug class: an empty parser token-list or string is indexed (value[0] / res[-1]) without first checking it is non-empty, so the parser escapes its own error-recovery contract.
Instance 1 — MIME parameter name ending with *
import email, email.policy
email.message_from_string("Content-Type: text/plain; name*\n\n",
policy=email.policy.default)['content-type'].params
get_parameter consumes the extended-parameter marker *, leaving value == '', then evaluates value[0] → IndexError. parse_mime_parameters only catches HeaderParseError, so the IndexError escapes. Also reachable via name*0* (sectioned) and a trailing x=1; name*.
Instance 2 — address display name that is only a comment
email.message_from_string("To: (c):\n\n", policy=email.policy.default)['to']
email.message_from_string("Cc: (x): a@b.com;\n\n", policy=email.policy.default)['cc']
DisplayName.display_name guards the empty-list case, but when the name is a single cfws token, res.pop(0) empties res and the subsequent res[-1] raises IndexError (this also propagates through the .value property). The second example is a syntactically valid RFC 5322 group whose display name is a comment.
Both are reachable from ordinary parsing of untrusted/malformed address and parameter headers under the modern policies.
Fix
Add minimal guards so each input degrades to the existing recovery path (a parse defect / empty display name), matching how the parser already treats other malformed input.
After the fix, 100k+ randomized message_from_string parses over malformed address and parameter headers produce no escaping non-HeaderParseError exception. (The empty-string IndexError still produced by directly calling the low-level get_* token parsers is their documented non-empty precondition and is not reachable from public header parsing — every caller checks non-empty first.)
Affected versions
Both instances reproduce on main and on the maintained 3.13 / 3.14 / 3.15 bugfix branches; the affected code (get_parameter and DisplayName.display_name) has been present since well before 3.9.
Linked PR
A PR fixing both instances follows.
Linked PRs
- gh-151858
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- 平均合併
- 1 天 9 小時
- 30 天內合併 PR
- 558
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
python/cpython 的其他 Issue
-
docs pending
難度 2/5 1-3 小時 新手友好度 78/100
-
stdlib type-feature
難度 2/5 1-3 小時 新手友好度 78/100
-
stdlib type-feature
難度 2/5 1-3 小時 新手友好度 72/100
-
build type-bug
難度 2/5 1-3 小時 新手友好度 76/100
-
stdlib topic-email type-feature
難度 2/5 1-3 小時 新手友好度 70/100
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 74/100
bancolombia/sentinel#23 ·
-
test md 未關閉CI
難度 2/5 1-3 小時 新手友好度 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
難度 2/5 1-3 小時 新手友好度 74/100
langchain-ai/deepagents#6450 ·
-
bug client
難度 2/5 1-3 小時 新手友好度 88/100
-
難度 2/5 1-3 小時 新手友好度 74/100