2017-06-14 13 views
0

は、emailパッケージと日付ヘッダーに無効な時間にメールをロードした後、dateヘッダにアクセスしようとすると、ValueError例外をスロースロー:メールは、Python 3.5または3.6を使用して例外

>>> import email 
>>> from email import policy 
>>> m = email.message_from_binary_file(open('bad_date.txt', 'rb'), policy=policy.default) 
>>> m['date'] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3.6/email/message.py", line 391, in __getitem__ 
    return self.get(name) 
    File "/usr/lib/python3.6/email/message.py", line 471, in get 
    return self.policy.header_fetch_parse(k, v) 
    File "/usr/lib/python3.6/email/policy.py", line 162, in header_fetch_parse 
    return self.header_factory(name, value) 
    File "/usr/lib/python3.6/email/headerregistry.py", line 586, in __call__ 
    return self[name](name, value) 
    File "/usr/lib/python3.6/email/headerregistry.py", line 197, in __new__ 
    cls.parse(value, kwds) 
    File "/usr/lib/python3.6/email/headerregistry.py", line 303, in parse 
    value = utils.parsedate_to_datetime(value) 
    File "/usr/lib/python3.6/email/utils.py", line 214, in parsedate_to_datetime 
    tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) 
ValueError: hour must be in 0..23 

これは、電子メールからヘッダです:

Date: Tue, 06 Jun 2017 27:39:33 +0600 

(私はスパムメールを分析していて、誰かの迷惑メール送信プログラムは、私はまた、負の時間を見てきましたタイムゾーンの変換の仕組みを理解していないようです。 ..)

emailパッケージは、電子メールの解析中に発生した問題に対処するように設計されています(この場合、例外をスローすると間違った結果になることがあります)。

この状況に対処するdefaultポリシーの一部であるデフォルトのheader_factoryを更新しようとする可能性がありますが、parsedate_to_datetimeがこのように動作するPythonのバグのようです。 (どうやらこの動作はon purposeです。)

UPDATE:

from email import policy 
from email import errors 
from email import _header_value_parser as parser 
from email.headerregistry import HeaderRegistry, DateHeader 


class DateHeaderRobust(DateHeader): 
    """ 
    Copied and updated from email/headerregistry.py to handle 
    ValueError returned by parsedate_to_datetime when a date header 
    has an invalid hour value (outside 0..23) 
    """ 

    @classmethod 
    def parse(cls, value, kwds): 
     try: 
      super().parse(value, kwds) 
     except ValueError: 
      kwds['defects'].append(
       errors.InvalidHeaderDefect('Invalid value in date')) 
      kwds['datetime'] = None 
      kwds['decoded'] = value 
      kwds['parse_tree'] = parser.TokenList() 


class UniqueDateHeader(DateHeaderRobust): 
    max_count = 1 


header_factory = HeaderRegistry() 
header_factory.map_to_type('date', UniqueDateHeader) 

email_policy = policy.default.clone(header_factory=header_factory) 

そしてメッセージを読む:私はPython bug

+0

?その日付が 'NONE'?それとも何か他のものに設定されている? –

+0

はい、私はparsedate_to_datetimeは' NONE'を返すことを期待したい、WHIは、 chはUniqueDateHeaderオブジェクトに 'datetime'属性として格納されます。 – TimB

+0

また、 'DateHeader'クラスは、欠陥を登録するためにわずかに変更する必要があります。その後、' none'となるので、parsedate_to_datetimeから返された値をさらに処理しようとしません。 – TimB

答えて

0

ここで私は今のところで行ってきた回避策だとしてこれを提起しました(あなたが起こるために何をしたいですか例えばemail.message_from_binary_file)と、kwargとしてpolicy=email_policyを使用。

関連する問題