Skip to content

Commit e9f706b

Browse files
committed
gh-152959: Raise ValueError for a <key> outside a <dict> in plistlib
_PlistParser.end_key evaluated self.stack[-1] before checking whether the stack was empty, so a <key> element outside a <dict> (for example at the document root) leaked an IndexError instead of a ValueError. Guard the empty-stack case, matching the sibling add_object handler. The binary plist format does not use this path and is unaffected.
1 parent 0a13efc commit e9f706b

3 files changed

Lines changed: 10 additions & 1 deletion

File tree

Lib/plistlib.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ def end_dict(self):
243243
self.stack.pop()
244244

245245
def end_key(self):
246-
if self.current_key or not isinstance(self.stack[-1], dict):
246+
if (self.current_key or not self.stack
247+
or not isinstance(self.stack[-1], dict)):
247248
raise ValueError("unexpected key at line %d" %
248249
self.parser.CurrentLineNumber)
249250
self.current_key = self.get_data()

Lib/test/test_plistlib.py

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

879+
def test_invalidkey(self):
880+
for xml in (b"<plist><key>x</key></plist>",
881+
b'<?xml version="1.0"?><key>x</key>',
882+
b"<plist><array><key>x</key></array></plist>"):
883+
self.assertRaises(ValueError, plistlib.loads, xml)
884+
879885
def test_integer_notations(self):
880886
pl = b"<plist><integer>456</integer></plist>"
881887
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 a ``<key>`` outside a
2+
``<dict>`` in an XML plist. Patch by tonghuaroot.

0 commit comments

Comments
 (0)