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
This commit is contained in:
Victor Stinner 2013-07-11 23:08:39 +02:00
parent 4d46343340
commit 71c8b7ec04
1 changed files with 14 additions and 8 deletions

View File

@ -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);