mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
[3.13] gh-133009: fix UAF in xml.etree.ElementTree.Element.__deepcopy__
(GH-133010) (#133806)
gh-133009: fix UAF in `xml.etree.ElementTree.Element.__deepcopy__` (GH-133010)
(cherry picked from commit 116a9f9b37
)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
parent
57efb77fef
commit
9718880ba9
3 changed files with 81 additions and 7 deletions
|
@ -2960,6 +2960,50 @@ class BadElementTest(ElementTestCase, unittest.TestCase):
|
|||
del b
|
||||
gc_collect()
|
||||
|
||||
def test_deepcopy_clear(self):
|
||||
# Prevent crashes when __deepcopy__() clears the children list.
|
||||
# See https://github.com/python/cpython/issues/133009.
|
||||
class X(ET.Element):
|
||||
def __deepcopy__(self, memo):
|
||||
root.clear()
|
||||
return self
|
||||
|
||||
root = ET.Element('a')
|
||||
evil = X('x')
|
||||
root.extend([evil, ET.Element('y')])
|
||||
if is_python_implementation():
|
||||
# Mutating a list over which we iterate raises an error.
|
||||
self.assertRaises(RuntimeError, copy.deepcopy, root)
|
||||
else:
|
||||
c = copy.deepcopy(root)
|
||||
# In the C implementation, we can still copy the evil element.
|
||||
self.assertListEqual(list(c), [evil])
|
||||
|
||||
def test_deepcopy_grow(self):
|
||||
# Prevent crashes when __deepcopy__() mutates the children list.
|
||||
# See https://github.com/python/cpython/issues/133009.
|
||||
a = ET.Element('a')
|
||||
b = ET.Element('b')
|
||||
c = ET.Element('c')
|
||||
|
||||
class X(ET.Element):
|
||||
def __deepcopy__(self, memo):
|
||||
root.append(a)
|
||||
root.append(b)
|
||||
return self
|
||||
|
||||
root = ET.Element('top')
|
||||
evil1, evil2 = X('1'), X('2')
|
||||
root.extend([evil1, c, evil2])
|
||||
children = list(copy.deepcopy(root))
|
||||
# mock deep copies
|
||||
self.assertIs(children[0], evil1)
|
||||
self.assertIs(children[2], evil2)
|
||||
# true deep copies
|
||||
self.assertEqual(children[1].tag, c.tag)
|
||||
self.assertEqual([c.tag for c in children[3:]],
|
||||
[a.tag, b.tag, a.tag, b.tag])
|
||||
|
||||
|
||||
class MutationDeleteElementPath(str):
|
||||
def __new__(cls, elem, *args):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue