From e131c7cf7893cdddc74caba2ca649b600dc6760b Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 25 Oct 2018 23:37:07 -0600 Subject: [2.7] Fix error handling bugs in _elementtree.c. (GH-10060) (GH-10080) Don't leak a reference if PyDict_Update() fails, check the PyList_New() call in treebuilder_new(), and properly handle failures in xmlparser(). (cherry picked from commit 9f3ed3e213b30059087d059a7d1d3b2527fa8654) --- Modules/_elementtree.c | 65 ++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b38e0ab..bbaf994 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -499,8 +499,10 @@ element(PyObject* self, PyObject* args, PyObject* kw) attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New(); if (!attrib) return NULL; - if (kw) - PyDict_Update(attrib, kw); + if (kw != NULL && PyDict_Update(attrib, kw) < 0) { + Py_DECREF(attrib); + return NULL; + } } else { Py_INCREF(Py_None); attrib = Py_None; @@ -530,8 +532,10 @@ subelement(PyObject* self, PyObject* args, PyObject* kw) attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New(); if (!attrib) return NULL; - if (kw) - PyDict_Update(attrib, kw); + if (kw != NULL && PyDict_Update(attrib, kw) < 0) { + Py_DECREF(attrib); + return NULL; + } } else { Py_INCREF(Py_None); attrib = Py_None; @@ -1727,12 +1731,16 @@ treebuilder_new(void) self->data = NULL; - self->stack = PyList_New(20); self->index = 0; self->events = NULL; self->start_event_obj = self->end_event_obj = NULL; self->start_ns_event_obj = self->end_ns_event_obj = NULL; + self->stack = PyList_New(20); + if (self->stack == NULL) { + Py_DECREF(self); + return NULL; + } ALLOC(sizeof(TreeBuilderObject), "create treebuilder"); @@ -1756,7 +1764,7 @@ treebuilder_dealloc(TreeBuilderObject* self) Py_XDECREF(self->end_event_obj); Py_XDECREF(self->start_event_obj); Py_XDECREF(self->events); - Py_DECREF(self->stack); + Py_XDECREF(self->stack); Py_XDECREF(self->data); Py_DECREF(self->last); Py_DECREF(self->this); @@ -2549,16 +2557,28 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw) if (self == NULL) return NULL; + /* Init to NULL to keep the error handling below manageable. */ + self->parser = NULL; + self->names = + self->target = + self->handle_xml = + self->handle_start = + self->handle_data = + self->handle_end = + self->handle_comment = + self->handle_pi = + self->handle_close = + NULL; + self->entity = PyDict_New(); if (!self->entity) { - PyObject_Del(self); + Py_DECREF(self); return NULL; } - + self->names = PyDict_New(); if (!self->names) { - PyObject_Del(self->entity); - PyObject_Del(self); + Py_DECREF(self); return NULL; } @@ -2568,9 +2588,7 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw) self->parser = EXPAT(ParserCreate_MM)(encoding, &memory_handler, "}"); if (!self->parser) { - PyObject_Del(self->names); - PyObject_Del(self->entity); - PyObject_Del(self); + Py_DECREF(self); PyErr_NoMemory(); return NULL; } @@ -2582,17 +2600,6 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw) ALLOC(sizeof(XMLParserObject), "create expatparser"); - /* Init to NULL to keep the error handling below manageable. */ - self->target = - self->handle_xml = - self->handle_start = - self->handle_data = - self->handle_end = - self->handle_comment = - self->handle_pi = - self->handle_close = - NULL; - /* setup target handlers */ if (!target) { target = treebuilder_new(); @@ -2678,7 +2685,9 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw) static void xmlparser_dealloc(XMLParserObject* self) { - EXPAT(ParserFree)(self->parser); + if (self->parser != NULL) { + EXPAT(ParserFree)(self->parser); + } Py_XDECREF(self->handle_close); Py_XDECREF(self->handle_pi); @@ -2688,9 +2697,9 @@ xmlparser_dealloc(XMLParserObject* self) Py_XDECREF(self->handle_start); Py_XDECREF(self->handle_xml); - Py_DECREF(self->target); - Py_DECREF(self->entity); - Py_DECREF(self->names); + Py_XDECREF(self->target); + Py_XDECREF(self->entity); + Py_XDECREF(self->names); RELEASE(sizeof(XMLParserObject), "destroy expatparser"); -- cgit v0.12