python / python/cpython

xml.sax expatreader: entity stack not cleaned up after error in external_entity_ref()

Open Beginner friendly
#148,448 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

stdlib topic-XML type-bug
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Follow-up from gh-148427 / PR #148435.

In ExpatParser.external_entity_ref() (Lib/xml/sax/expatreader.py), when an exception occurs during external entity parsing, the _entity_stack cleanup (restoring self._parser and self._source) is skipped because except Exception: return 0 exits the method before reaching lines 430–431:

try:
    xmlreader.IncrementalParser.parse(self, source)
except Exception:
    return 0  # exits here, cleanup below never runs

(self._parser, self._source) = self._entity_stack[-1]  # skipped
del self._entity_stack[-1]                               # skipped
return 1

After an error, self._parser still points to the sub-parser for the external entity, self._source points to the entity's input source, and the original parser/source pair is stuck in _entity_stack.

In practice this probably doesn't matter much since the parser is usually abandoned after a SAXParseException, but it's still a state corruption if someone tries to reuse the parser or inspect its state after catching the exception.

A finally clause would fix this, but that was intentionally kept out of gh-148427 to keep the scope minimal.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading ExpatParser.external_entity_ref() in Lib/xml/sax/expatreader.py and the related gh-148427 / PR #148435 context. Done means an exception during external entity parsing no longer leaves self._parser, self._source, or _entity_stack in the corrupted state described.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.