From 9bfd41b93ce7a3bac3e4f8ec826bb633b4bafb8c Mon Sep 17 00:00:00 2001 From: Ho Cheung Date: Tue, 21 Apr 2026 23:25:12 +0800 Subject: [PATCH] gh-148731: Fix Element.iter() crash on OOM Initialize the Element iterator state needed for OOM handling before allocating parent_stack, and keep the OOM regression test scoped to the test that uses _testcapi. Add a regression test for the MemoryError path in Element.iter(). --- Lib/test/test_xml_etree_c.py | 20 ++++++++++++++++++- ...-04-21-22-30-06.gh-issue-148731.imNLch.rst | 3 +++ Modules/_elementtree.c | 5 +++-- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-04-21-22-30-06.gh-issue-148731.imNLch.rst diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index 270b9d6da8e7b9..c07855b2efb78e 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -2,7 +2,7 @@ import io import struct from test import support -from test.support.import_helper import import_fresh_module +from test.support.import_helper import import_fresh_module, import_module import types import unittest @@ -183,6 +183,24 @@ def __hash__(self): r = e.get(X()) self.assertIsNone(r) + @unittest.skipIf(support.Py_TRACE_REFS, + 'Py_TRACE_REFS conflicts with testcapi.set_nomemory') + def test_iter_oom_no_crash(self): + # gh-148731: OOM while creating an Element iterator should raise + # MemoryError without crashing while deallocating a partially + # initialized iterator object. + testcapi = import_module('_testcapi') + element = cET.Element('root') + raised = False + testcapi.set_nomemory(1, 2) + try: + element.iter() + except MemoryError: + raised = True + finally: + testcapi.remove_mem_hooks() + self.assertTrue(raised, "MemoryError not raised") + @support.cpython_only def test_immutable_types(self): root = cET.fromstring('') diff --git a/Misc/NEWS.d/next/Library/2026-04-21-22-30-06.gh-issue-148731.imNLch.rst b/Misc/NEWS.d/next/Library/2026-04-21-22-30-06.gh-issue-148731.imNLch.rst new file mode 100644 index 00000000000000..518eaf0bb0bd19 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-21-22-30-06.gh-issue-148731.imNLch.rst @@ -0,0 +1,3 @@ +Fix a crash in :mod:`xml.etree.ElementTree` when +:meth:`~xml.etree.ElementTree.Element.iter` fails with :exc:`MemoryError` +while creating the C accelerator iterator. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index e2185c4bd03aad..fb0d73f91e4a20 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2359,6 +2359,9 @@ create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag, if (!it) return NULL; + it->parent_stack_used = 0; + it->parent_stack_size = INIT_PARENT_STACK_SIZE; + it->sought_tag = Py_NewRef(tag); it->gettext = gettext; it->root_element = (ElementObject*)Py_NewRef(self); @@ -2369,8 +2372,6 @@ create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag, PyErr_NoMemory(); return NULL; } - it->parent_stack_used = 0; - it->parent_stack_size = INIT_PARENT_STACK_SIZE; PyObject_GC_Track(it);