Skip to content

Commit a2c145c

Browse files
Issue #24091: Fixed various crashes in corner cases in C implementation of
ElementTree.
2 parents c0937f7 + 5bf3120 commit a2c145c

3 files changed

Lines changed: 221 additions & 46 deletions

File tree

Lib/test/test_xml_etree.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,126 @@ def test_pickle_issue18997(self):
17091709
self.assertEqual(e2[0].tag, 'dogs')
17101710

17111711

1712+
class BadElementTest(ElementTestCase, unittest.TestCase):
1713+
def test_extend_mutable_list(self):
1714+
class X:
1715+
@property
1716+
def __class__(self):
1717+
L[:] = [ET.Element('baz')]
1718+
return ET.Element
1719+
L = [X()]
1720+
e = ET.Element('foo')
1721+
try:
1722+
e.extend(L)
1723+
except TypeError:
1724+
pass
1725+
1726+
class Y(X, ET.Element):
1727+
pass
1728+
L = [Y('x')]
1729+
e = ET.Element('foo')
1730+
e.extend(L)
1731+
1732+
def test_extend_mutable_list2(self):
1733+
class X:
1734+
@property
1735+
def __class__(self):
1736+
del L[:]
1737+
return ET.Element
1738+
L = [X(), ET.Element('baz')]
1739+
e = ET.Element('foo')
1740+
try:
1741+
e.extend(L)
1742+
except TypeError:
1743+
pass
1744+
1745+
class Y(X, ET.Element):
1746+
pass
1747+
L = [Y('bar'), ET.Element('baz')]
1748+
e = ET.Element('foo')
1749+
e.extend(L)
1750+
1751+
def test_remove_with_mutating(self):
1752+
class X(ET.Element):
1753+
def __eq__(self, o):
1754+
del e[:]
1755+
return False
1756+
e = ET.Element('foo')
1757+
e.extend([X('bar')])
1758+
self.assertRaises(ValueError, e.remove, ET.Element('baz'))
1759+
1760+
e = ET.Element('foo')
1761+
e.extend([ET.Element('bar')])
1762+
self.assertRaises(ValueError, e.remove, X('baz'))
1763+
1764+
1765+
class MutatingElementPath(str):
1766+
def __new__(cls, elem, *args):
1767+
self = str.__new__(cls, *args)
1768+
self.elem = elem
1769+
return self
1770+
def __eq__(self, o):
1771+
del self.elem[:]
1772+
return True
1773+
MutatingElementPath.__hash__ = str.__hash__
1774+
1775+
class BadElementPath(str):
1776+
def __eq__(self, o):
1777+
raise 1/0
1778+
BadElementPath.__hash__ = str.__hash__
1779+
1780+
class BadElementPathTest(ElementTestCase, unittest.TestCase):
1781+
def setUp(self):
1782+
super().setUp()
1783+
from xml.etree import ElementPath
1784+
self.path_cache = ElementPath._cache
1785+
ElementPath._cache = {}
1786+
1787+
def tearDown(self):
1788+
from xml.etree import ElementPath
1789+
ElementPath._cache = self.path_cache
1790+
super().tearDown()
1791+
1792+
def test_find_with_mutating(self):
1793+
e = ET.Element('foo')
1794+
e.extend([ET.Element('bar')])
1795+
e.find(MutatingElementPath(e, 'x'))
1796+
1797+
def test_find_with_error(self):
1798+
e = ET.Element('foo')
1799+
e.extend([ET.Element('bar')])
1800+
try:
1801+
e.find(BadElementPath('x'))
1802+
except ZeroDivisionError:
1803+
pass
1804+
1805+
def test_findtext_with_mutating(self):
1806+
e = ET.Element('foo')
1807+
e.extend([ET.Element('bar')])
1808+
e.findtext(MutatingElementPath(e, 'x'))
1809+
1810+
def test_findtext_with_error(self):
1811+
e = ET.Element('foo')
1812+
e.extend([ET.Element('bar')])
1813+
try:
1814+
e.findtext(BadElementPath('x'))
1815+
except ZeroDivisionError:
1816+
pass
1817+
1818+
def test_findall_with_mutating(self):
1819+
e = ET.Element('foo')
1820+
e.extend([ET.Element('bar')])
1821+
e.findall(MutatingElementPath(e, 'x'))
1822+
1823+
def test_findall_with_error(self):
1824+
e = ET.Element('foo')
1825+
e.extend([ET.Element('bar')])
1826+
try:
1827+
e.findall(BadElementPath('x'))
1828+
except ZeroDivisionError:
1829+
pass
1830+
1831+
17121832
class ElementTreeTypeTest(unittest.TestCase):
17131833
def test_istype(self):
17141834
self.assertIsInstance(ET.ParseError, type)
@@ -2556,6 +2676,8 @@ def test_main(module=None):
25562676
ModuleTest,
25572677
ElementSlicingTest,
25582678
BasicElementTest,
2679+
BadElementTest,
2680+
BadElementPathTest,
25592681
ElementTreeTest,
25602682
IOTest,
25612683
ParseErrorTest,

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Core and Builtins
4949
Library
5050
-------
5151

52+
- Issue #24091: Fixed various crashes in corner cases in C implementation of
53+
ElementTree.
54+
5255
- Issue #21931: msilib.FCICreate() now raises TypeError in the case of a bad
5356
argument instead of a ValueError with a bogus FCI error number.
5457
Patch by Jeffrey Armstrong.

0 commit comments

Comments
 (0)