Bug report
plistlib.loads on an XML plist whose <key> element appears outside a
<dict> raises an uncaught IndexError instead of a ValueError.
_PlistParser.end_key checks self.stack[-1] without first testing whether
the stack is empty:
def end_key(self):
if self.current_key or not isinstance(self.stack[-1], dict):
raise ValueError("unexpected key at line %d" %
self.parser.CurrentLineNumber)
self.current_key = self.get_data()
When a <key> is the document's top-level element there is no enclosing
container on the stack, so self.stack[-1] raises IndexError.
Reproducer:
>>> import plistlib
>>> plistlib.loads(b"<plist><key>x</key></plist>")
Traceback (most recent call last):
...
IndexError: list index out of range
The sibling handler add_object (used by <integer>, <string>, etc.)
already guards the empty-stack case with elif not self.stack:, so scalar
elements at the top level are handled cleanly. A <key> outside a <dict>
should likewise raise a ValueError, consistent with the other malformed
inputs the parser rejects.
The binary plist format does not use this code path and is unaffected.
Versions
3.15 (main); the same code is present on 3.13 and 3.14.
Linked PRs
Bug report
plistlib.loadson an XML plist whose<key>element appears outside a<dict>raises an uncaughtIndexErrorinstead of aValueError._PlistParser.end_keychecksself.stack[-1]without first testing whetherthe stack is empty:
When a
<key>is the document's top-level element there is no enclosingcontainer on the stack, so
self.stack[-1]raisesIndexError.Reproducer:
The sibling handler
add_object(used by<integer>,<string>, etc.)already guards the empty-stack case with
elif not self.stack:, so scalarelements at the top level are handled cleanly. A
<key>outside a<dict>should likewise raise a
ValueError, consistent with the other malformedinputs the parser rejects.
The binary plist format does not use this code path and is unaffected.
Versions
3.15 (main); the same code is present on 3.13 and 3.14.
Linked PRs