Fix imap parsing non rfc compliant date crash (#93630)

* Fix imap parsing non rfc compliant date crash

* Use parsedate_to_datetime from mail.utils
This commit is contained in:
Jan Bouwhuis 2023-05-28 13:28:11 +02:00 committed by GitHub
parent 202c9071a4
commit 4c0d169cfc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 20 deletions

View file

@ -5,6 +5,8 @@ import asyncio
from collections.abc import Mapping
from datetime import datetime, timedelta
import email
from email.header import decode_header, make_header
from email.utils import parseaddr, parsedate_to_datetime
import logging
from typing import Any
@ -82,9 +84,9 @@ class ImapMessage:
"""Get the email headers."""
header_base: dict[str, tuple[str,]] = {}
for key, value in self.email_message.items():
header: tuple[str,] = (str(value),)
if header_base.setdefault(key, header) != header:
header_base[key] += header # type: ignore[assignment]
header_instances: tuple[str,] = (str(value),)
if header_base.setdefault(key, header_instances) != header_instances:
header_base[key] += header_instances # type: ignore[assignment]
return header_base
@property
@ -94,23 +96,26 @@ class ImapMessage:
date_str: str | None
if (date_str := self.email_message["Date"]) is None:
return None
# In some cases a timezone or comment is added in parenthesis after the date
# We want to strip that part to avoid parsing errors
return datetime.strptime(
date_str.split("(")[0].strip(), "%a, %d %b %Y %H:%M:%S %z"
)
try:
mail_dt_tm = parsedate_to_datetime(date_str)
except ValueError:
_LOGGER.debug(
"Parsed date %s is not compliant with rfc2822#section-3.3", date_str
)
return None
return mail_dt_tm
@property
def sender(self) -> str:
"""Get the parsed message sender from the email."""
return str(email.utils.parseaddr(self.email_message["From"])[1])
return str(parseaddr(self.email_message["From"])[1])
@property
def subject(self) -> str:
"""Decode the message subject."""
decoded_header = email.header.decode_header(self.email_message["Subject"])
header = email.header.make_header(decoded_header)
return str(header)
decoded_header = decode_header(self.email_message["Subject"])
subject_header = make_header(decoded_header)
return str(subject_header)
@property
def text(self) -> str: