gh-115398: Expose Expat >=2.6.0 reparse deferral API (CVE-2023-52425)… · hartwork/cpython@6a95676 (original) (raw)
`@@ -121,10 +121,6 @@
`
121
121
`
`
122
122
`"""
`
123
123
``
124
``
`-
fails_with_expat_2_6_0 = (unittest.expectedFailure
`
125
``
`-
if pyexpat.version_info >= (2, 6, 0) else
`
126
``
`-
lambda test: test)
`
127
``
-
128
124
`def checkwarnings(*filters, quiet=False):
`
129
125
`def decorator(test):
`
130
126
`def newtest(*args, **kwargs):
`
`@@ -1462,12 +1458,14 @@ def test_attlist_default(self):
`
1462
1458
``
1463
1459
`class XMLPullParserTest(unittest.TestCase):
`
1464
1460
``
1465
``
`-
def _feed(self, parser, data, chunk_size=None):
`
``
1461
`+
def _feed(self, parser, data, chunk_size=None, flush=False):
`
1466
1462
`if chunk_size is None:
`
1467
1463
`parser.feed(data)
`
1468
1464
`else:
`
1469
1465
`for i in range(0, len(data), chunk_size):
`
1470
1466
`parser.feed(data[i:i+chunk_size])
`
``
1467
`+
if flush:
`
``
1468
`+
parser.flush()
`
1471
1469
``
1472
1470
`def assert_events(self, parser, expected, max_events=None):
`
1473
1471
`self.assertEqual(
`
`@@ -1485,34 +1483,32 @@ def assert_event_tags(self, parser, expected, max_events=None):
`
1485
1483
`self.assertEqual([(action, elem.tag) for action, elem in events],
`
1486
1484
`expected)
`
1487
1485
``
1488
``
`-
def test_simple_xml(self, chunk_size=None):
`
``
1486
`+
def test_simple_xml(self, chunk_size=None, flush=False):
`
1489
1487
`parser = ET.XMLPullParser()
`
1490
1488
`self.assert_event_tags(parser, [])
`
1491
``
`-
self._feed(parser, "\n", chunk_size)
`
``
1489
`+
self._feed(parser, "\n", chunk_size, flush)
`
1492
1490
`self.assert_event_tags(parser, [])
`
1493
1491
`self._feed(parser,
`
1494
1492
`"\n text</element",
`
1495
``
`-
chunk_size)
`
``
1493
`+
chunk_size, flush)
`
1496
1494
`self.assert_event_tags(parser, [])
`
1497
``
`-
self._feed(parser, ">\n", chunk_size)
`
``
1495
`+
self._feed(parser, ">\n", chunk_size, flush)
`
1498
1496
`self.assert_event_tags(parser, [('end', 'element')])
`
1499
``
`-
self._feed(parser, "texttail\n", chunk_size)
`
1500
``
`-
self._feed(parser, "\n", chunk_size)
`
``
1497
`+
self._feed(parser, "texttail\n", chunk_size, flush)
`
``
1498
`+
self._feed(parser, "\n", chunk_size, flush)
`
1501
1499
`self.assert_event_tags(parser, [
`
1502
1500
` ('end', 'element'),
`
1503
1501
` ('end', 'empty-element'),
`
1504
1502
` ])
`
1505
``
`-
self._feed(parser, "\n", chunk_size)
`
``
1503
`+
self._feed(parser, "\n", chunk_size, flush)
`
1506
1504
`self.assert_event_tags(parser, [('end', 'root')])
`
1507
1505
`self.assertIsNone(parser.close())
`
1508
1506
``
1509
``
`-
@fails_with_expat_2_6_0
`
1510
1507
`def test_simple_xml_chunk_1(self):
`
1511
``
`-
self.test_simple_xml(chunk_size=1)
`
``
1508
`+
self.test_simple_xml(chunk_size=1, flush=True)
`
1512
1509
``
1513
``
`-
@fails_with_expat_2_6_0
`
1514
1510
`def test_simple_xml_chunk_5(self):
`
1515
``
`-
self.test_simple_xml(chunk_size=5)
`
``
1511
`+
self.test_simple_xml(chunk_size=5, flush=True)
`
1516
1512
``
1517
1513
`def test_simple_xml_chunk_22(self):
`
1518
1514
`self.test_simple_xml(chunk_size=22)
`
`@@ -1711,6 +1707,57 @@ def test_unknown_event(self):
`
1711
1707
`with self.assertRaises(ValueError):
`
1712
1708
`ET.XMLPullParser(events=('start', 'end', 'bogus'))
`
1713
1709
``
``
1710
`+
def test_flush_reparse_deferral_enabled(self):
`
``
1711
`+
if pyexpat.version_info < (2, 6, 0):
`
``
1712
`+
self.skipTest(f'Expat {pyexpat.version_info} does not '
`
``
1713
`+
'support reparse deferral')
`
``
1714
+
``
1715
`+
parser = ET.XMLPullParser(events=('start', 'end'))
`
``
1716
+
``
1717
`+
for chunk in ("<doc", ">"):
`
``
1718
`+
parser.feed(chunk)
`
``
1719
+
``
1720
`+
self.assert_event_tags(parser, []) # i.e. no elements started
`
``
1721
`+
if ET is pyET:
`
``
1722
`+
self.assertTrue(parser._parser._parser.GetReparseDeferralEnabled())
`
``
1723
+
``
1724
`+
parser.flush()
`
``
1725
+
``
1726
`+
self.assert_event_tags(parser, [('start', 'doc')])
`
``
1727
`+
if ET is pyET:
`
``
1728
`+
self.assertTrue(parser._parser._parser.GetReparseDeferralEnabled())
`
``
1729
+
``
1730
`+
parser.feed("")
`
``
1731
`+
parser.close()
`
``
1732
+
``
1733
`+
self.assert_event_tags(parser, [('end', 'doc')])
`
``
1734
+
``
1735
`+
def test_flush_reparse_deferral_disabled(self):
`
``
1736
`+
parser = ET.XMLPullParser(events=('start', 'end'))
`
``
1737
+
``
1738
`+
for chunk in ("<doc", ">"):
`
``
1739
`+
parser.feed(chunk)
`
``
1740
+
``
1741
`+
if pyexpat.version_info >= (2, 6, 0):
`
``
1742
`+
if not ET is pyET:
`
``
1743
`+
self.skipTest(f'XMLParser.(Get|Set)ReparseDeferralEnabled '
`
``
1744
`+
'methods not available in C')
`
``
1745
`+
parser._parser._parser.SetReparseDeferralEnabled(False)
`
``
1746
+
``
1747
`+
self.assert_event_tags(parser, []) # i.e. no elements started
`
``
1748
`+
if ET is pyET:
`
``
1749
`+
self.assertFalse(parser._parser._parser.GetReparseDeferralEnabled())
`
``
1750
+
``
1751
`+
parser.flush()
`
``
1752
+
``
1753
`+
self.assert_event_tags(parser, [('start', 'doc')])
`
``
1754
`+
if ET is pyET:
`
``
1755
`+
self.assertFalse(parser._parser._parser.GetReparseDeferralEnabled())
`
``
1756
+
``
1757
`+
parser.feed("")
`
``
1758
`+
parser.close()
`
``
1759
+
``
1760
`+
self.assert_event_tags(parser, [('end', 'doc')])
`
1714
1761
``
1715
1762
`#
`
1716
1763
`# xinclude tests (samples from appendix C of the xinclude specification)
`