mirror of
https://github.com/python/cpython
synced 2024-09-16 00:07:33 +00:00
gh-95087: Fix IndexError in parsing invalid date in the email module (GH-95201)
Co-authored-by: wouter bolsterlee <wouter@bolsterl.ee>
This commit is contained in:
parent
5956de16cd
commit
ea5ed0ba51
|
@ -95,6 +95,8 @@ def _parsedate_tz(data):
|
||||||
return None
|
return None
|
||||||
data = data[:5]
|
data = data[:5]
|
||||||
[dd, mm, yy, tm, tz] = data
|
[dd, mm, yy, tm, tz] = data
|
||||||
|
if not (dd and mm and yy):
|
||||||
|
return None
|
||||||
mm = mm.lower()
|
mm = mm.lower()
|
||||||
if mm not in _monthnames:
|
if mm not in _monthnames:
|
||||||
dd, mm = mm, dd.lower()
|
dd, mm = mm, dd.lower()
|
||||||
|
@ -110,6 +112,8 @@ def _parsedate_tz(data):
|
||||||
yy, tm = tm, yy
|
yy, tm = tm, yy
|
||||||
if yy[-1] == ',':
|
if yy[-1] == ',':
|
||||||
yy = yy[:-1]
|
yy = yy[:-1]
|
||||||
|
if not yy:
|
||||||
|
return None
|
||||||
if not yy[0].isdigit():
|
if not yy[0].isdigit():
|
||||||
yy, tz = tz, yy
|
yy, tz = tz, yy
|
||||||
if tm[-1] == ',':
|
if tm[-1] == ',':
|
||||||
|
|
|
@ -3047,33 +3047,43 @@ def test_formatdate_usegmt(self):
|
||||||
|
|
||||||
# parsedate and parsedate_tz will become deprecated interfaces someday
|
# parsedate and parsedate_tz will become deprecated interfaces someday
|
||||||
def test_parsedate_returns_None_for_invalid_strings(self):
|
def test_parsedate_returns_None_for_invalid_strings(self):
|
||||||
self.assertIsNone(utils.parsedate(''))
|
# See also test_parsedate_to_datetime_with_invalid_raises_valueerror
|
||||||
self.assertIsNone(utils.parsedate_tz(''))
|
# in test_utils.
|
||||||
self.assertIsNone(utils.parsedate(' '))
|
invalid_dates = [
|
||||||
self.assertIsNone(utils.parsedate_tz(' '))
|
'',
|
||||||
self.assertIsNone(utils.parsedate('0'))
|
' ',
|
||||||
self.assertIsNone(utils.parsedate_tz('0'))
|
'0',
|
||||||
self.assertIsNone(utils.parsedate('A Complete Waste of Time'))
|
'A Complete Waste of Time',
|
||||||
self.assertIsNone(utils.parsedate_tz('A Complete Waste of Time'))
|
'Wed, 3 Apr 2002 12.34.56.78+0800',
|
||||||
self.assertIsNone(utils.parsedate_tz('Wed, 3 Apr 2002 12.34.56.78+0800'))
|
'17 June , 2022',
|
||||||
|
'Friday, -Nov-82 16:14:55 EST',
|
||||||
|
'Friday, Nov--82 16:14:55 EST',
|
||||||
|
'Friday, 19-Nov- 16:14:55 EST',
|
||||||
|
]
|
||||||
|
for dtstr in invalid_dates:
|
||||||
|
with self.subTest(dtstr=dtstr):
|
||||||
|
self.assertIsNone(utils.parsedate(dtstr))
|
||||||
|
self.assertIsNone(utils.parsedate_tz(dtstr))
|
||||||
# Not a part of the spec but, but this has historically worked:
|
# Not a part of the spec but, but this has historically worked:
|
||||||
self.assertIsNone(utils.parsedate(None))
|
self.assertIsNone(utils.parsedate(None))
|
||||||
self.assertIsNone(utils.parsedate_tz(None))
|
self.assertIsNone(utils.parsedate_tz(None))
|
||||||
|
|
||||||
def test_parsedate_compact(self):
|
def test_parsedate_compact(self):
|
||||||
|
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26 +0800'),
|
||||||
|
(2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800))
|
||||||
# The FWS after the comma is optional
|
# The FWS after the comma is optional
|
||||||
self.assertEqual(utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'),
|
self.assertEqual(utils.parsedate_tz('Wed,3 Apr 2002 14:58:26 +0800'),
|
||||||
utils.parsedate('Wed, 3 Apr 2002 14:58:26 +0800'))
|
(2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800))
|
||||||
|
# The comma is optional
|
||||||
|
self.assertEqual(utils.parsedate_tz('Wed 3 Apr 2002 14:58:26 +0800'),
|
||||||
|
(2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800))
|
||||||
|
|
||||||
def test_parsedate_no_dayofweek(self):
|
def test_parsedate_no_dayofweek(self):
|
||||||
eq = self.assertEqual
|
|
||||||
eq(utils.parsedate_tz('25 Feb 2003 13:47:26 -0800'),
|
|
||||||
(2003, 2, 25, 13, 47, 26, 0, 1, -1, -28800))
|
|
||||||
|
|
||||||
def test_parsedate_compact_no_dayofweek(self):
|
|
||||||
eq = self.assertEqual
|
eq = self.assertEqual
|
||||||
eq(utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'),
|
eq(utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'),
|
||||||
(2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800))
|
(2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800))
|
||||||
|
eq(utils.parsedate_tz('February 5, 2003 13:47:26 -0800'),
|
||||||
|
(2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800))
|
||||||
|
|
||||||
def test_parsedate_no_space_before_positive_offset(self):
|
def test_parsedate_no_space_before_positive_offset(self):
|
||||||
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26+0800'),
|
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26+0800'),
|
||||||
|
@ -3084,7 +3094,6 @@ def test_parsedate_no_space_before_negative_offset(self):
|
||||||
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26-0800'),
|
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26-0800'),
|
||||||
(2002, 4, 3, 14, 58, 26, 0, 1, -1, -28800))
|
(2002, 4, 3, 14, 58, 26, 0, 1, -1, -28800))
|
||||||
|
|
||||||
|
|
||||||
def test_parsedate_accepts_time_with_dots(self):
|
def test_parsedate_accepts_time_with_dots(self):
|
||||||
eq = self.assertEqual
|
eq = self.assertEqual
|
||||||
eq(utils.parsedate_tz('5 Feb 2003 13.47.26 -0800'),
|
eq(utils.parsedate_tz('5 Feb 2003 13.47.26 -0800'),
|
||||||
|
@ -3092,6 +3101,20 @@ def test_parsedate_accepts_time_with_dots(self):
|
||||||
eq(utils.parsedate_tz('5 Feb 2003 13.47 -0800'),
|
eq(utils.parsedate_tz('5 Feb 2003 13.47 -0800'),
|
||||||
(2003, 2, 5, 13, 47, 0, 0, 1, -1, -28800))
|
(2003, 2, 5, 13, 47, 0, 0, 1, -1, -28800))
|
||||||
|
|
||||||
|
def test_parsedate_rfc_850(self):
|
||||||
|
self.assertEqual(utils.parsedate_tz('Friday, 19-Nov-82 16:14:55 EST'),
|
||||||
|
(1982, 11, 19, 16, 14, 55, 0, 1, -1, -18000))
|
||||||
|
|
||||||
|
def test_parsedate_no_seconds(self):
|
||||||
|
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58 +0800'),
|
||||||
|
(2002, 4, 3, 14, 58, 0, 0, 1, -1, 28800))
|
||||||
|
|
||||||
|
def test_parsedate_dot_time_delimiter(self):
|
||||||
|
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14.58.26 +0800'),
|
||||||
|
(2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800))
|
||||||
|
self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14.58 +0800'),
|
||||||
|
(2002, 4, 3, 14, 58, 0, 0, 1, -1, 28800))
|
||||||
|
|
||||||
def test_parsedate_acceptable_to_time_functions(self):
|
def test_parsedate_acceptable_to_time_functions(self):
|
||||||
eq = self.assertEqual
|
eq = self.assertEqual
|
||||||
timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800')
|
timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800')
|
||||||
|
|
|
@ -49,12 +49,21 @@ def test_parsedate_to_datetime_naive(self):
|
||||||
self.naive_dt)
|
self.naive_dt)
|
||||||
|
|
||||||
def test_parsedate_to_datetime_with_invalid_raises_valueerror(self):
|
def test_parsedate_to_datetime_with_invalid_raises_valueerror(self):
|
||||||
invalid_dates = ['',
|
# See also test_parsedate_returns_None_for_invalid_strings in test_email.
|
||||||
'0',
|
invalid_dates = [
|
||||||
'A Complete Waste of Time'
|
'',
|
||||||
'Tue, 06 Jun 2017 27:39:33 +0600',
|
' ',
|
||||||
'Tue, 06 Jun 2017 07:39:33 +2600',
|
'0',
|
||||||
'Tue, 06 Jun 2017 27:39:33']
|
'A Complete Waste of Time',
|
||||||
|
'Wed, 3 Apr 2002 12.34.56.78+0800'
|
||||||
|
'Tue, 06 Jun 2017 27:39:33 +0600',
|
||||||
|
'Tue, 06 Jun 2017 07:39:33 +2600',
|
||||||
|
'Tue, 06 Jun 2017 27:39:33',
|
||||||
|
'17 June , 2022',
|
||||||
|
'Friday, -Nov-82 16:14:55 EST',
|
||||||
|
'Friday, Nov--82 16:14:55 EST',
|
||||||
|
'Friday, 19-Nov- 16:14:55 EST',
|
||||||
|
]
|
||||||
for dtstr in invalid_dates:
|
for dtstr in invalid_dates:
|
||||||
with self.subTest(dtstr=dtstr):
|
with self.subTest(dtstr=dtstr):
|
||||||
self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr)
|
self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix IndexError in parsing invalid date in the :mod:`email` module.
|
Loading…
Reference in a new issue