gh-115398: Expose Expat >=2.6.0 reparse deferral API (CVE-2023-52425) (GH-115623)

Allow controlling Expat >=2.6.0 reparse deferral (CVE-2023-52425) by adding five new methods:

- `xml.etree.ElementTree.XMLParser.flush`
- `xml.etree.ElementTree.XMLPullParser.flush`
- `xml.parsers.expat.xmlparser.GetReparseDeferralEnabled`
- `xml.parsers.expat.xmlparser.SetReparseDeferralEnabled`
- `xml.sax.expatreader.ExpatParser.flush`

Based on the "flush" idea from https://github.com/python/cpython/pull/115138#issuecomment-1932444270 .

### Notes

- Please treat as a security fix related to CVE-2023-52425.

Includes code suggested-by: Snild Dolkow <snild@sony.com>
and by core dev Serhiy Storchaka.
This commit is contained in:
Sebastian Pipping 2024-02-29 23:52:50 +01:00 committed by GitHub
parent d01886c5c9
commit 6a95676bb5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 435 additions and 21 deletions

View file

@ -1320,6 +1320,11 @@ class XMLPullParser:
else:
yield event
def flush(self):
if self._parser is None:
raise ValueError("flush() called after end of stream")
self._parser.flush()
def XML(text, parser=None):
"""Parse XML document from string constant.
@ -1726,6 +1731,15 @@ class XMLParser:
del self.parser, self._parser
del self.target, self._target
def flush(self):
was_enabled = self.parser.GetReparseDeferralEnabled()
try:
self.parser.SetReparseDeferralEnabled(False)
self.parser.Parse(b"", False)
except self._error as v:
self._raiseerror(v)
finally:
self.parser.SetReparseDeferralEnabled(was_enabled)
# --------------------------------------------------------------------
# C14N 2.0