diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 93f3ef5e38af84..3fa548e63f84d9 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -139,16 +139,22 @@ def _decode_base64(s): def _date_from_string(s, aware_datetime): order = ('year', 'month', 'day', 'hour', 'minute', 'second') - gd = _dateParser.match(s).groupdict() + m = _dateParser.match(s) + if m is None: + raise ValueError(f"invalid date string: {s!r}") + gd = m.groupdict() lst = [] for key in order: val = gd[key] if val is None: break lst.append(int(val)) - if aware_datetime: - return datetime.datetime(*lst, tzinfo=datetime.UTC) - return datetime.datetime(*lst) + try: + if aware_datetime: + return datetime.datetime(*lst, tzinfo=datetime.UTC) + return datetime.datetime(*lst) + except (TypeError, ValueError): + raise ValueError(f"invalid date string: {s!r}") from None def _date_to_string(d, aware_datetime): diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index b9c261310bb567..b9025f81e63205 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -876,6 +876,13 @@ def test_invalidreal(self): self.assertRaises(ValueError, plistlib.loads, b"not real") + def test_invaliddate(self): + for xml in (b"not a date", + b"", + b"2004Z", + b"2004-11Z"): + self.assertRaises(ValueError, plistlib.loads, xml) + def test_integer_notations(self): pl = b"456" value = plistlib.loads(pl) diff --git a/Misc/NEWS.d/next/Library/2026-07-03-12-29-41.gh-issue-152957.Cat86k.rst b/Misc/NEWS.d/next/Library/2026-07-03-12-29-41.gh-issue-152957.Cat86k.rst new file mode 100644 index 00000000000000..c7b20e39f5a0a9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-03-12-29-41.gh-issue-152957.Cat86k.rst @@ -0,0 +1,2 @@ +:mod:`plistlib` now raises :exc:`ValueError` for an invalid ```` in an +XML plist. Patch by tonghuaroot.