summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-09-18 05:29:37 -0700
committerGitHub <noreply@github.com>2017-09-18 05:29:37 -0700
commite727d41ffcd91b21ce82026ec8c8381d34a16209 (patch)
tree6fe96261c5baf6fe58a218c6c1d3649d931c8606 /Lib
parent9b47af65375fab9318e88ccb061394a36c8c6c33 (diff)
downloadcpython-git-e727d41ffcd91b21ce82026ec8c8381d34a16209.tar.gz
bpo-31499, xml.etree: Fix xmlparser_gc_clear() crash (#3641)
* bpo-31499, xml.etree: Fix xmlparser_gc_clear() crash xml.etree: xmlparser_gc_clear() now sets self.parser to NULL to prevent a crash in xmlparser_dealloc() if xmlparser_gc_clear() was called previously by the garbage collector, because the parser was part of a reference cycle. Co-Authored-By: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_xml_etree_c.py20
1 files changed, 20 insertions, 0 deletions
diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py
index 171a3f88b9..25517a7269 100644
--- a/Lib/test/test_xml_etree_c.py
+++ b/Lib/test/test_xml_etree_c.py
@@ -65,6 +65,26 @@ class MiscTests(unittest.TestCase):
del root
support.gc_collect()
+ def test_parser_ref_cycle(self):
+ # bpo-31499: xmlparser_dealloc() crashed with a segmentation fault when
+ # xmlparser_gc_clear() was called previously by the garbage collector,
+ # when the parser was part of a reference cycle.
+
+ def parser_ref_cycle():
+ parser = cET.XMLParser()
+ # Create a reference cycle using an exception to keep the frame
+ # alive, so the parser will be destroyed by the garbage collector
+ try:
+ raise ValueError
+ except ValueError as exc:
+ err = exc
+
+ # Create a parser part of reference cycle
+ parser_ref_cycle()
+ # Trigger an explicit garbage collection to break the reference cycle
+ # and so destroy the parser
+ support.gc_collect()
+
@unittest.skipUnless(cET, 'requires _elementtree')
class TestAliasWorking(unittest.TestCase):