diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index 2144d203e1e95c..a06e57a457ac57 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -5,6 +5,7 @@ from test.support import import_fresh_module import types import unittest +import sys cET = import_fresh_module('xml.etree.ElementTree', fresh=['_elementtree']) diff --git a/Misc/NEWS.d/next/Library/2017-10-11-19-29-37.bpo-31758.kbeqNQ.rst b/Misc/NEWS.d/next/Library/2017-10-11-19-29-37.bpo-31758.kbeqNQ.rst new file mode 100644 index 00000000000000..156361ea467bd4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-11-19-29-37.bpo-31758.kbeqNQ.rst @@ -0,0 +1,2 @@ +Prevent reference leaks in ``_elementtree.Element.__setstate__()``. Patch by +Oren Milman. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b88e8a1d6e9eb4..171cae093d972f 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1051,6 +1051,10 @@ element_setstate_from_attributes(ElementObject *self, oldextra->attrib = Py_None; } + /* Decref each of the old children. */ + for (i = 0; i < self->extra->length; i++) { + Py_CLEAR(self->extra->children[i]); + } /* Copy children */ for (i = 0; i < nchildren; i++) { PyObject *child = PyList_GET_ITEM(children, i); @@ -3660,11 +3664,11 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, const char *encoding) /*[clinic end generated code: output=3ae45ec6cdf344e4 input=96288fcba916cfce]*/ { - self->entity = PyDict_New(); + Py_XSETREF(self->entity, PyDict_New()); if (!self->entity) return -1; - self->names = PyDict_New(); + Py_XSETREF(self->names, PyDict_New()); if (!self->names) { Py_CLEAR(self->entity); return -1; @@ -3693,41 +3697,43 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, return -1; } } - self->target = target; + Py_XSETREF(self->target, target); - self->handle_start_ns = PyObject_GetAttrString(target, "start_ns"); + Py_XSETREF(self->handle_start_ns, PyObject_GetAttrString(target, "start_ns")); if (ignore_attribute_error(self->handle_start_ns)) { return -1; } - self->handle_end_ns = PyObject_GetAttrString(target, "end_ns"); + Py_XSETREF(self->handle_end_ns, PyObject_GetAttrString(target, "end_ns")); if (ignore_attribute_error(self->handle_end_ns)) { return -1; } - self->handle_start = PyObject_GetAttrString(target, "start"); + Py_XSETREF(self->handle_start, PyObject_GetAttrString(target, "start")); if (ignore_attribute_error(self->handle_start)) { return -1; } - self->handle_data = PyObject_GetAttrString(target, "data"); + Py_XSETREF(self->handle_data, PyObject_GetAttrString(target, "data")); if (ignore_attribute_error(self->handle_data)) { return -1; } - self->handle_end = PyObject_GetAttrString(target, "end"); + Py_XSETREF(self->handle_end, PyObject_GetAttrString(target, "end")); if (ignore_attribute_error(self->handle_end)) { return -1; } - self->handle_comment = PyObject_GetAttrString(target, "comment"); + Py_XSETREF(self->handle_comment, + PyObject_GetAttrString(target, "comment")); if (ignore_attribute_error(self->handle_comment)) { return -1; } - self->handle_pi = PyObject_GetAttrString(target, "pi"); + Py_XSETREF(self->handle_pi, PyObject_GetAttrString(target, "pi")); if (ignore_attribute_error(self->handle_pi)) { return -1; } - self->handle_close = PyObject_GetAttrString(target, "close"); + Py_XSETREF(self->handle_close, PyObject_GetAttrString(target, "close")); if (ignore_attribute_error(self->handle_close)) { return -1; } - self->handle_doctype = PyObject_GetAttrString(target, "doctype"); + Py_XSETREF(self->handle_doctype, + PyObject_GetAttrString(target, "doctype")); if (ignore_attribute_error(self->handle_doctype)) { return -1; }