Skip to content

Commit 273ae93

Browse files
committed
gh-152957: Raise ValueError for invalid <date> in plistlib
_date_from_string did _dateParser.match(s).groupdict(). On a non-matching value match() returns None (AttributeError); on a partial match (the regex allows year-only and year-month) too few fields reach datetime.datetime(*lst) (TypeError). Both now raise ValueError, matching the sibling <integer> and <real> elements. The binary plist format decodes dates with struct.unpack and is unaffected.
1 parent 0a13efc commit 273ae93

3 files changed

Lines changed: 19 additions & 4 deletions

File tree

Lib/plistlib.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,22 @@ def _decode_base64(s):
139139

140140
def _date_from_string(s, aware_datetime):
141141
order = ('year', 'month', 'day', 'hour', 'minute', 'second')
142-
gd = _dateParser.match(s).groupdict()
142+
m = _dateParser.match(s)
143+
if m is None:
144+
raise ValueError(f"invalid date string: {s!r}")
145+
gd = m.groupdict()
143146
lst = []
144147
for key in order:
145148
val = gd[key]
146149
if val is None:
147150
break
148151
lst.append(int(val))
149-
if aware_datetime:
150-
return datetime.datetime(*lst, tzinfo=datetime.UTC)
151-
return datetime.datetime(*lst)
152+
try:
153+
if aware_datetime:
154+
return datetime.datetime(*lst, tzinfo=datetime.UTC)
155+
return datetime.datetime(*lst)
156+
except (TypeError, ValueError):
157+
raise ValueError(f"invalid date string: {s!r}") from None
152158

153159

154160
def _date_to_string(d, aware_datetime):

Lib/test/test_plistlib.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,13 @@ def test_invalidreal(self):
876876
self.assertRaises(ValueError, plistlib.loads,
877877
b"<plist><integer>not real</integer></plist>")
878878

879+
def test_invaliddate(self):
880+
for xml in (b"<plist><date>not a date</date></plist>",
881+
b"<plist><date></date></plist>",
882+
b"<plist><date>2004Z</date></plist>",
883+
b"<plist><date>2004-11Z</date></plist>"):
884+
self.assertRaises(ValueError, plistlib.loads, xml)
885+
879886
def test_integer_notations(self):
880887
pl = b"<plist><integer>456</integer></plist>"
881888
value = plistlib.loads(pl)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`plistlib` now raises :exc:`ValueError` for an invalid ``<date>`` in an
2+
XML plist. Patch by tonghuaroot.

0 commit comments

Comments
 (0)