Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-126033: fix a crash inxml.etree.ElementTree.Element.remove when concurrent mutations happen#126124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
picnixz merged 31 commits intopython:mainfrompicnixz:fix/xml-evil-remove-126033
Mar 31, 2025
Merged
Changes from1 commit
Commits
Show all changes
31 commits
Select commitHold shift + click to select a range
abc121c
Add versioning to XML elements.
picnixzOct 27, 2024
4efa517
fix tests
picnixzOct 27, 2024
4ca3cf0
fix portability issues
picnixzOct 27, 2024
a1950d1
fixup
picnixzOct 28, 2024
9b6f559
unify versioning
picnixzOct 29, 2024
00a7a7e
handle evil mutations in `Element.remove`
picnixzOct 29, 2024
59ade8f
blurb
picnixzOct 29, 2024
7fc9932
improve NEWS entry formulation
picnixzDec 6, 2024
e30756d
remove versioning
picnixzDec 8, 2024
f2b5bb1
fix tests
picnixzDec 8, 2024
9f73517
improve detection and tests
picnixzDec 15, 2024
70f2aad
revert whitespaces
picnixzDec 15, 2024
756b1eb
amend NEWS
picnixzDec 17, 2024
4b74caf
improve test coverage
picnixzDec 17, 2024
fd29203
align C implementation with Python implementation as much as possible
picnixzDec 17, 2024
e7033b6
fix tests and improve coverage
picnixzDec 17, 2024
4d3cdd7
fix tests (i'll explain afterwards)
picnixzDec 17, 2024
883e8d2
improve comments
picnixzDec 17, 2024
220b669
change root name to avoid special wildcards
picnixzDec 19, 2024
7f26430
avoid strong reference on the child to remove
picnixzDec 19, 2024
e8d84c8
address Serhiy's review
picnixzDec 19, 2024
3a43c0f
Merge branch 'main' into fix/xml-evil-remove-126033
picnixzJan 19, 2025
bc52c04
Update Misc/NEWS.d/next/Library/2024-10-29-12-59-45.gh-issue-126033.s…
picnixzFeb 4, 2025
f4a4dae
remove un-necessary subtest parameter
picnixzFeb 8, 2025
09a9fa9
Reduce the visual size of the tests
picnixzFeb 8, 2025
f5d352f
fixup docs
picnixzFeb 8, 2025
2b47468
Merge branch 'main' into fix/xml-evil-remove-126033
picnixzFeb 8, 2025
dc576ab
Merge branch 'main' into fix/xml-evil-remove-126033
picnixzFeb 22, 2025
ce66ac7
Merge branch 'main' into fix/xml-evil-remove-126033
picnixzMar 14, 2025
04cb600
do not pedantically test the pure Python implementation
picnixzMar 15, 2025
a0c2324
Merge branch 'main' into fix/xml-evil-remove-126033
picnixzMar 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
fix tests and improve coverage
  • Loading branch information
@picnixz
picnixz committedDec 17, 2024
commite7033b63b1da09e3cf9b6391c40f5f876938a784
114 changes: 57 additions & 57 deletionsLib/test/test_xml_etree.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2643,10 +2643,6 @@ def test_pickle_issue18997(self):

class BadElementTest(ElementTestCase, unittest.TestCase):

@classmethod
def setUpClass(cls):
cls.is_c = ET is not pyET

def test_extend_mutable_list(self):
class X:
@property
Expand DownExpand Up@@ -2695,80 +2691,84 @@ def test_remove_with_clear(self):

E = ET.Element

class X1(E):
def __eq__(self, o):
del root[:]
return False

class X2(E):
def __eq__(self, o):
root.clear()
return False

class Y1(E):
def __eq__(self, o):
del root[:]
return True

class Y2(E):
def __eq__(self, o):
root.clear()
return True

def test_remove(root, target, raises):
if raises:
self.assertRaises(ValueError, root.remove, target)
else:
root.remove(target)
self.assertNotIn(target, root)

for etype, rem_type, raises in [
(E, X1, True), (E, X2, True),
(X1, E, True), (X2, E, True),
(Y1, E, self.is_c), (Y2, E, self.is_c),
(E, Y1, self.is_c), (E, Y2, self.is_c),
]:
with self.subTest(etype=etype, rem_type=rem_type, raises=raises):
with self.subTest("single child"):
root = E('.')
root.append(etype('one'))
test_remove(root, rem_type('baz'), raises)

with self.subTest("with children"):
root = E('.')
root.extend([etype('one'), rem_type('two')])
test_remove(root, rem_type('baz'), raises)

def test_remove_with_mutate_root(self):
for raises in [True, False]:

class X(E):
def __eq__(self, o):
del root[:]
return not raises

class Y(E):
def __eq__(self, o):
root.clear()
return not raises

for etype, rem_type in [(E, X), (X, E), (E, Y), (Y, E)]:
with self.subTest(
etype=etype, rem_type=rem_type, raises=raises,
):
with self.subTest("single child"):
root = E('.')
root.append(etype('one'))
test_remove(root, rem_type('baz'), raises)

with self.subTest("with children"):
root = E('.')
root.extend([etype('one'), rem_type('two')])
test_remove(root, rem_type('baz'), raises)

def test_remove_with_mutate_root_1(self):
# See: https://github.com/python/cpython/issues/126033

E = ET.Element

class X(ET.Element):
class X(E):
def __eq__(self, o):
del root[0]
return False

class Y(ET.Element):
for etype, rem_type in [(E, X), (X, E)]:
with self.subTest('missing', etype=etype, rem_type=rem_type):
root = E('.')
root.extend([E('one'), etype('two')])
to_remove = rem_type('baz')
self.assertRaises(ValueError, root.remove, to_remove)

with self.subTest('existing', etype=etype, rem_type=rem_type):
root = E('.')
root.extend([E('one'), etype('same')])
to_remove = rem_type('same')
self.assertRaises(ValueError, root.remove, to_remove)

def test_remove_with_mutate_root_2(self):
# See: https://github.com/python/cpython/issues/126033

E = ET.Element

class X(E):
def __eq__(self, o):
del root[0]
return True

for bar_type, rem_type, raises in [
(E, X, True),
(X, E, True),
(Y, E, True),
(E, Y, False),
]:
with self.subTest(bar_type=bar_type, rem_type=rem_type, raises=raises):
for etype, rem_type in [(E, X), (X, E)]:
with self.subTest('missing', etype=etype, rem_type=rem_type):
root = E('.')
root.extend([E('first'),rem_type('bar')])
root.extend([E('one'),etype('two')])
to_remove = rem_type('baz')
if raises:
self.assertRaises(ValueError, root.remove, to_remove)
else:
root.remove(to_remove)
self.assertNotIn(to_remove, root)
root.remove(to_remove)

with self.subTest('existing', etype=etype, rem_type=rem_type):
root = E('.')
root.extend([E('one'), etype('same')])
to_remove = rem_type('same')
root.remove(to_remove)

@support.infinite_recursion(25)
def test_recursive_repr(self):
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp