bpo-31544: Fix a reference leak to 'self' after the previous target error handling fixes. (GH-6318)

This change generally splits the xmlparser creation code into an unsafe part with "rollback" error handling and a safe "object initialisation done" part with normal decref cleanup.
This commit is contained in:
scoder 2018-03-31 14:23:30 +02:00 committed by Serhiy Storchaka
parent 7f48a426fc
commit c498cd8bf8
2 changed files with 23 additions and 6 deletions

View File

@ -0,0 +1,2 @@
The C accelerator module of ElementTree ignored exceptions raised when
looking up TreeBuilder target methods in XMLParser().

View File

@ -2575,14 +2575,24 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw)
return NULL;
}
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();
if (!target) {
EXPAT(ParserFree)(self->parser);
PyObject_Del(self->names);
PyObject_Del(self->entity);
PyObject_Del(self);
Py_DECREF(self);
return NULL;
}
} else
@ -2591,30 +2601,37 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw)
self->handle_xml = PyObject_GetAttrString(target, "xml");
if (ignore_attribute_error(self->handle_xml)) {
Py_DECREF(self);
return NULL;
}
self->handle_start = PyObject_GetAttrString(target, "start");
if (ignore_attribute_error(self->handle_start)) {
Py_DECREF(self);
return NULL;
}
self->handle_data = PyObject_GetAttrString(target, "data");
if (ignore_attribute_error(self->handle_data)) {
Py_DECREF(self);
return NULL;
}
self->handle_end = PyObject_GetAttrString(target, "end");
if (ignore_attribute_error(self->handle_end)) {
Py_DECREF(self);
return NULL;
}
self->handle_comment = PyObject_GetAttrString(target, "comment");
if (ignore_attribute_error(self->handle_comment)) {
Py_DECREF(self);
return NULL;
}
self->handle_pi = PyObject_GetAttrString(target, "pi");
if (ignore_attribute_error(self->handle_pi)) {
Py_DECREF(self);
return NULL;
}
self->handle_close = PyObject_GetAttrString(target, "close");
if (ignore_attribute_error(self->handle_close)) {
Py_DECREF(self);
return NULL;
}
@ -2650,8 +2667,6 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw)
);
#endif
ALLOC(sizeof(XMLParserObject), "create expatparser");
return (PyObject*) self;
}