fix(email): guard _decode_header against unknown MIME charset (#1354)
A header that declares an unknown or invalid MIME charset (e.g. a malformed or spam Subject like =?x-unknown-charset?B?...?=) raised an uncaught LookupError. bytes.decode(..., errors="replace") only handles byte-decode errors, not codec *lookup* failures, so the "replace" safety net did not apply. _decode_header decodes Subject/From/To/Cc for the inbox list, single-message fetch, and the background mail pollers (routes/email_routes.py, routes/email_pollers.py, src/builtin_actions.py), so a single bad message could crash the whole inbox render or the poller loop. Wrap the per-part decode in try/except (LookupError, ValueError) and fall back to utf-8/replace. Valid charsets (utf-8, iso-8859-1, ...) are unchanged. Adds tests/test_email_decode_header.py — the unknown-charset case fails before this change and passes after.
This commit is contained in:
@@ -751,7 +751,13 @@ def _decode_header(raw):
|
||||
decoded = []
|
||||
for data, charset in parts:
|
||||
if isinstance(data, bytes):
|
||||
decoded.append(data.decode(charset or "utf-8", errors="replace"))
|
||||
try:
|
||||
decoded.append(data.decode(charset or "utf-8", errors="replace"))
|
||||
except (LookupError, ValueError):
|
||||
# Unknown/invalid MIME charset (e.g. a malformed or spam header
|
||||
# like =?x-unknown-charset?B?...?=). errors="replace" only covers
|
||||
# byte-decode errors, not codec lookup, so fall back to utf-8.
|
||||
decoded.append(data.decode("utf-8", errors="replace"))
|
||||
else:
|
||||
decoded.append(data)
|
||||
return " ".join(decoded)
|
||||
|
||||
Reference in New Issue
Block a user