Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions 6 Lib/email/headerregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,13 @@ def parse(cls, value, kwds):
kwds['parse_tree'] = parser.TokenList()
return
if isinstance(value, str):
kwds['decoded'] = value
value = utils.parsedate_to_datetime(value)
if value is None:
kwds['defects'].append(errors.InvalidHeaderDefect('Invalid value in date'))
kwds['datetime'] = None
kwds['parse_tree'] = parser.TokenList()
return
kwds['datetime'] = value
kwds['decoded'] = utils.format_datetime(kwds['datetime'])
kwds['parse_tree'] = cls.value_parser(kwds['decoded'])
Expand Down
18 changes: 13 additions & 5 deletions 18 Lib/email/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,19 @@ def make_msgid(idstring=None, domain=None):


def parsedate_to_datetime(data):
*dtuple, tz = _parsedate_tz(data)
if tz is None:
return datetime.datetime(*dtuple[:6])
return datetime.datetime(*dtuple[:6],
tzinfo=datetime.timezone(datetime.timedelta(seconds=tz)))
try:
*dtuple, tz = _parsedate_tz(data)
except TypeError:
# _parsedate_tz(data) returned None due to failure to parse
return None
try:
if tz is None:
return datetime.datetime(*dtuple[:6])
return datetime.datetime(*dtuple[:6],
tzinfo=datetime.timezone(datetime.timedelta(seconds=tz)))
except ValueError:
# Date parsed ok, but one or more component values are invalid
return None


def parseaddr(addr):
Expand Down
6 changes: 4 additions & 2 deletions 6 Lib/test/test_email/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ def __init__(self, *args, **kw):
# Backward compatibility to minimize test_email test changes.
ndiffAssertEqual = unittest.TestCase.assertEqual

def _msgobj(self, filename):
def _msgobj(self, filename, policy=None):
if policy is None:
policy = self.policy
with openfile(filename) as fp:
return email.message_from_file(fp, policy=self.policy)
return email.message_from_file(fp, policy=policy)

def _str_msg(self, string, message=None, policy=None):
if policy is None:
Expand Down
6 changes: 6 additions & 0 deletions 6 Lib/test/test_email/data/msg_47.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Date: Tue, 06 Jun 2017 27:39:33 +0600
From: "123@abuse.net" <123@example.com>
To: <123@abuse.net>
Subject: VIARGA|CIALIS|LEVITRA

### PHARRMACY ON1INE 24/7 ###
31 changes: 27 additions & 4 deletions 31 Lib/test/test_email/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from email import iterators
from email import base64mime
from email import quoprimime
from email._policybase import compat32

from test.support import unlink, start_threads
from test.test_email import openfile, TestEmailBase
Expand Down Expand Up @@ -759,6 +760,10 @@ def test_unicode_body_defaults_to_utf8_encoding(self):
w4kgdGVzdGFiYwo=
"""))

def test_date_header_from_message_with_invalid_date(self):
msg = self._msgobj('msg_47.txt', policy=email.policy.default)
self.assertEqual(msg['date'], 'Tue, 06 Jun 2017 27:39:33 +0600')


# Test the email.encoders module
class TestEncoders(unittest.TestCase):
Expand Down Expand Up @@ -2710,10 +2715,12 @@ class TestIdempotent(TestEmailBase):

linesep = '\n'

def _msgobj(self, filename):
def _msgobj(self, filename, policy=None):
if policy is None:
policy = self.policy
with openfile(filename) as fp:
data = fp.read()
msg = email.message_from_string(data)
msg = email.message_from_string(data, policy=policy)
return msg, data

def _idempotent(self, msg, text, unixfrom=False):
Expand Down Expand Up @@ -2815,6 +2822,10 @@ def test_message_signed_idempotent(self):
msg, text = self._msgobj('msg_45.txt')
self._idempotent(msg, text)

def test_invalid_date(self):
msg, text = self._msgobj('msg_47.txt', policy=email.policy.default)
self._idempotent(msg, text)

def test_content_type(self):
eq = self.assertEqual
# Get a message object and reset the seek pointer for other tests
Expand Down Expand Up @@ -3012,6 +3023,16 @@ def test_parsedate_acceptable_to_time_functions(self):
eq(time.localtime(t)[:6], timetup[:6])
eq(int(time.strftime('%Y', timetup[:9])), 2003)

def test_parsedate_to_datetime_returns_None_for_invalid_strings(self):
self.assertIsNone(utils.parsedate_to_datetime(''))
self.assertIsNone(utils.parsedate_to_datetime('0'))
self.assertIsNone(utils.parsedate_to_datetime('A Complete Waste of Time'))

def test_parsedate_to_datetime_returns_None_for_invalid_dates(self):
self.assertIsNone(utils.parsedate_to_datetime('Tue, 06 Jun 2017 27:39:33 +0600'))
self.assertIsNone(utils.parsedate_to_datetime('Tue, 06 Jun 2017 07:39:33 +2600'))
self.assertIsNone(utils.parsedate_to_datetime('Tue, 06 Jun 2017 27:39:33'))

def test_mktime_tz(self):
self.assertEqual(utils.mktime_tz((1970, 1, 1, 0, 0, 0,
-1, -1, -1, 0)), 0)
Expand Down Expand Up @@ -4154,11 +4175,13 @@ class BaseTestBytesGeneratorIdempotent:

maxDiff = None

def _msgobj(self, filename):
def _msgobj(self, filename, policy=None):
if policy is None:
policy = self.policy
with openfile(filename, 'rb') as fp:
data = fp.read()
data = self.normalize_linesep_regex.sub(self.blinesep, data)
msg = email.message_from_bytes(data)
msg = email.message_from_bytes(data, policy=policy)
return msg, data

def _idempotent(self, msg, data, unixfrom=False):
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.