From: Victor Stinner Date: Thu, 11 Jul 2013 21:08:39 +0000 (+0200) Subject: Issue #18408: Different fixes in _elementtree.c to handle correctly MemoryError X-Git-Tag: v3.4.0a1~247 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71c8b7ec0464628633954333038af2f8174c10be;p=python Issue #18408: Different fixes in _elementtree.c to handle correctly MemoryError * create_new_element() initializes all attributes before handling errors, to fix a crash in the destructor * create_new_element() calls PyObject_GC_Del() on error, instead of PyObject_Del(), because the object was created by PyObject_GC_New() * subelement() now handles create_new_element() failure * element_getattro() now handles element_get_text() failure * makeuniversal() now handles PyBytes_FromStringAndSize() failure --- diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index a5b3ec5eae..9a71c4376a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -224,13 +224,6 @@ create_new_element(PyObject* tag, PyObject* attrib) return NULL; self->extra = NULL; - if (attrib != Py_None && !is_empty_dict(attrib)) { - if (create_extra(self, attrib) < 0) { - PyObject_Del(self); - return NULL; - } - } - Py_INCREF(tag); self->tag = tag; @@ -242,6 +235,13 @@ create_new_element(PyObject* tag, PyObject* attrib) self->weakreflist = NULL; + if (attrib != Py_None && !is_empty_dict(attrib)) { + if (create_extra(self, attrib) < 0) { + PyObject_GC_Del(self); + return NULL; + } + } + ALLOC(sizeof(ElementObject), "create element"); PyObject_GC_Track(self); return (PyObject*) self; @@ -530,6 +530,8 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) elem = create_new_element(tag, attrib); Py_DECREF(attrib); + if (elem == NULL) + return NULL; if (element_add_subelement(parent, elem) < 0) { Py_DECREF(elem); @@ -1748,7 +1750,7 @@ element_getattro(ElementObject* self, PyObject* nameobj) return res; } else if (strcmp(name, "text") == 0) { res = element_get_text(self); - Py_INCREF(res); + Py_XINCREF(res); return res; } @@ -2726,6 +2728,10 @@ makeuniversal(XMLParserObject* self, const char* string) if (i != size) { /* convert to universal name */ tag = PyBytes_FromStringAndSize(NULL, size+1); + if (tag == NULL) { + Py_DECREF(key); + return NULL; + } p = PyBytes_AS_STRING(tag); p[0] = '{'; memcpy(p+1, string, size);