From e5bd2488d41809af4f983c0c0530b0cae1f4f350 Mon Sep 17 00:00:00 2001 From: Vyron Vasileiadis Date: Sat, 18 Jul 2026 01:59:22 +0300 Subject: [PATCH] gh-153854: Raise ValueError from imaplib.Time2Internaldate on empty string Time2Internaldate() is documented to raise ValueError for input that is not of a known type, and its final branch does so. However, the string branch subscripted the value with date_time[0]/date_time[-1] before that check, so an empty string escaped as a bare IndexError. Use str.startswith() and str.endswith() instead, which handle the empty string gracefully while preserving behaviour for every other input. --- Lib/imaplib.py | 2 +- Lib/test/test_imaplib.py | 14 ++++++++++++++ Misc/ACKS | 1 + .../2026-07-18-01-50-34.gh-issue-153854.z8ec1p.rst | 3 +++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-18-01-50-34.gh-issue-153854.z8ec1p.rst diff --git a/Lib/imaplib.py b/Lib/imaplib.py index 139da1d3bb6fb8..1939ea05c81b2c 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -2272,7 +2272,7 @@ def Time2Internaldate(date_time): if date_time.tzinfo is None: raise ValueError("date_time must be aware") dt = date_time - elif isinstance(date_time, str) and (date_time[0],date_time[-1]) == ('"','"'): + elif isinstance(date_time, str) and date_time.startswith('"') and date_time.endswith('"'): return date_time # Assume in correct format else: raise ValueError("date_time not of a known type") diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 100791a9c3eb2c..3b05962fe4b9cd 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -159,6 +159,20 @@ def test_that_Time2Internaldate_returns_a_result(self): for t in self.timevalues(): imaplib.Time2Internaldate(t) + def test_Time2Internaldate_quoted_string_passthrough(self): + # An already double-quoted string is assumed to be in the + # correct format and returned unchanged. + quoted = '"18-May-2033 05:33:20 +0200"' + self.assertEqual(imaplib.Time2Internaldate(quoted), quoted) + + def test_Time2Internaldate_bad_string(self): + # A string that is not double-quoted is not of a known type and + # must raise ValueError, including the empty string (gh-153854). + for value in ('', 'x', '"x', 'x"'): + with self.subTest(value=value): + with self.assertRaises(ValueError): + imaplib.Time2Internaldate(value) + @socket_helper.skip_if_tcp_blackhole def test_imap4_host_default_value(self): # Check whether the IMAP4_PORT is truly unavailable. diff --git a/Misc/ACKS b/Misc/ACKS index fec00c1b272f4e..5fe1d8cd1121ee 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -2008,6 +2008,7 @@ Wm. Keith van der Meulen Eric N. Vander Weele Andrew Vant Atul Varma +Vyron Vasileiadis Dmitry Vasiliev Sebastian Ortiz Vasquez Alexandre Vassalotti diff --git a/Misc/NEWS.d/next/Library/2026-07-18-01-50-34.gh-issue-153854.z8ec1p.rst b/Misc/NEWS.d/next/Library/2026-07-18-01-50-34.gh-issue-153854.z8ec1p.rst new file mode 100644 index 00000000000000..d2d04d5a46b14d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-18-01-50-34.gh-issue-153854.z8ec1p.rst @@ -0,0 +1,3 @@ +:func:`imaplib.Time2Internaldate` now raises :exc:`ValueError` instead of +:exc:`IndexError` when passed an empty string, consistent with its documented +behaviour for strings that are not of a known type.