diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2022-07-25 06:17:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-25 06:17:25 (GMT) |
commit | ea5ed0ba51c10cfdde7651a475438551964dfdfc (patch) | |
tree | 3f427ac4b9f85eafd0a9fbeb2ab8fec7035a6504 | |
parent | 5956de16cd00e7e1cf5cbf3d7b4a930eaa928321 (diff) | |
download | cpython-ea5ed0ba51c10cfdde7651a475438551964dfdfc.zip cpython-ea5ed0ba51c10cfdde7651a475438551964dfdfc.tar.gz cpython-ea5ed0ba51c10cfdde7651a475438551964dfdfc.tar.bz2 |
gh-95087: Fix IndexError in parsing invalid date in the email module (GH-95201)
Co-authored-by: wouter bolsterlee <wouter@bolsterl.ee>
-rw-r--r-- | Lib/email/_parseaddr.py | 4 | ||||
-rw-r--r-- | Lib/test/test_email/test_email.py | 57 | ||||
-rw-r--r-- | Lib/test/test_email/test_utils.py | 21 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst | 1 |
4 files changed, 60 insertions, 23 deletions
diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py index ba5ad5a..febe411 100644 --- a/Lib/email/_parseaddr.py +++ b/Lib/email/_parseaddr.py @@ -95,6 +95,8 @@ def _parsedate_tz(data): return None data = data[:5] [dd, mm, yy, tm, tz] = data + if not (dd and mm and yy): + return None mm = mm.lower() if mm not in _monthnames: dd, mm = mm, dd.lower() @@ -110,6 +112,8 @@ def _parsedate_tz(data): yy, tm = tm, yy if yy[-1] == ',': yy = yy[:-1] + if not yy: + return None if not yy[0].isdigit(): yy, tz = tz, yy if tm[-1] == ',': diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 0bf679b..44b4057 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3047,33 +3047,43 @@ class TestMiscellaneous(TestEmailBase): # parsedate and parsedate_tz will become deprecated interfaces someday def test_parsedate_returns_None_for_invalid_strings(self): - self.assertIsNone(utils.parsedate('')) - self.assertIsNone(utils.parsedate_tz('')) - self.assertIsNone(utils.parsedate(' ')) - self.assertIsNone(utils.parsedate_tz(' ')) - self.assertIsNone(utils.parsedate('0')) - self.assertIsNone(utils.parsedate_tz('0')) - self.assertIsNone(utils.parsedate('A Complete Waste of Time')) - self.assertIsNone(utils.parsedate_tz('A Complete Waste of Time')) - self.assertIsNone(utils.parsedate_tz('Wed, 3 Apr 2002 12.34.56.78+0800')) + # See also test_parsedate_to_datetime_with_invalid_raises_valueerror + # in test_utils. + invalid_dates = [ + '', + ' ', + '0', + 'A Complete Waste of Time', + '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: self.assertIsNone(utils.parsedate(None)) self.assertIsNone(utils.parsedate_tz(None)) 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 - self.assertEqual(utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'), - utils.parsedate('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)) + # 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): 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(utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'), (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): self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26+0800'), @@ -3084,7 +3094,6 @@ class TestMiscellaneous(TestEmailBase): 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_accepts_time_with_dots(self): eq = self.assertEqual eq(utils.parsedate_tz('5 Feb 2003 13.47.26 -0800'), @@ -3092,6 +3101,20 @@ class TestMiscellaneous(TestEmailBase): eq(utils.parsedate_tz('5 Feb 2003 13.47 -0800'), (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): eq = self.assertEqual timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800') diff --git a/Lib/test/test_email/test_utils.py b/Lib/test/test_email/test_utils.py index e3d3eae..78afb35 100644 --- a/Lib/test/test_email/test_utils.py +++ b/Lib/test/test_email/test_utils.py @@ -49,12 +49,21 @@ class DateTimeTests(unittest.TestCase): self.naive_dt) def test_parsedate_to_datetime_with_invalid_raises_valueerror(self): - invalid_dates = ['', - '0', - 'A Complete Waste of Time' - 'Tue, 06 Jun 2017 27:39:33 +0600', - 'Tue, 06 Jun 2017 07:39:33 +2600', - 'Tue, 06 Jun 2017 27:39:33'] + # See also test_parsedate_returns_None_for_invalid_strings in test_email. + invalid_dates = [ + '', + ' ', + '0', + '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: with self.subTest(dtstr=dtstr): self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr) diff --git a/Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst b/Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst new file mode 100644 index 0000000..48a5c1a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst @@ -0,0 +1 @@ +Fix IndexError in parsing invalid date in the :mod:`email` module. |