mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-15 11:10:58 +08:00
Patch 3/4: _mysql.c reference counting and exception issues
This patch fixes a reference leak and improves the error handling in the converter mapping code. Rather accidentially it also drops the cleanup: label and the gotos ;) https://sourceforge.net/p/mysql-python/patches/79/
This commit is contained in:
@ -407,8 +407,13 @@ _mysql_ResultObject_Initialize(
|
|||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist,
|
||||||
&conn, &use, &conv))
|
&conn, &use, &conv))
|
||||||
return -1;
|
return -1;
|
||||||
if (!conv) conv = PyDict_New();
|
if (!conv) {
|
||||||
if (!conv) return -1;
|
if (!(conv = PyDict_New()))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Py_INCREF(conv);
|
||||||
|
|
||||||
self->conn = (PyObject *) conn;
|
self->conn = (PyObject *) conn;
|
||||||
Py_INCREF(conn);
|
Py_INCREF(conn);
|
||||||
self->use = use;
|
self->use = use;
|
||||||
@ -425,31 +430,47 @@ _mysql_ResultObject_Initialize(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
self->converter = PyTuple_New(0);
|
self->converter = PyTuple_New(0);
|
||||||
|
Py_DECREF(conv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
n = mysql_num_fields(result);
|
n = mysql_num_fields(result);
|
||||||
self->nfields = n;
|
self->nfields = n;
|
||||||
if (!(self->converter = PyTuple_New(n))) return -1;
|
if (!(self->converter = PyTuple_New(n))) {
|
||||||
|
Py_DECREF(conv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
fields = mysql_fetch_fields(result);
|
fields = mysql_fetch_fields(result);
|
||||||
for (i=0; i<n; i++) {
|
for (i=0; i<n; i++) {
|
||||||
PyObject *tmp, *fun;
|
PyObject *tmp, *fun;
|
||||||
tmp = PyInt_FromLong((long) fields[i].type);
|
tmp = PyInt_FromLong((long) fields[i].type);
|
||||||
if (!tmp) return -1;
|
if (!tmp) {
|
||||||
|
Py_DECREF(conv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
fun = PyObject_GetItem(conv, tmp);
|
fun = PyObject_GetItem(conv, tmp);
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
if (!fun) {
|
if (!fun) {
|
||||||
PyErr_Clear();
|
if (PyErr_Occurred()) {
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
|
Py_DECREF(conv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
fun = Py_None;
|
fun = Py_None;
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
}
|
}
|
||||||
if (PySequence_Check(fun)) {
|
else if (PySequence_Check(fun)) {
|
||||||
int j, n2=PySequence_Size(fun);
|
int j, n2=PySequence_Size(fun);
|
||||||
PyObject *fun2=NULL;
|
PyObject *fun2=NULL;
|
||||||
for (j=0; j<n2; j++) {
|
for (j=0; j<n2; j++) {
|
||||||
PyObject *t = PySequence_GetItem(fun, j);
|
PyObject *t = PySequence_GetItem(fun, j);
|
||||||
if (!t) continue;
|
if (!t) {
|
||||||
if (!PyTuple_Check(t)) goto cleanup;
|
Py_DECREF(fun);
|
||||||
if (PyTuple_GET_SIZE(t) == 2) {
|
Py_DECREF(conv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (PyTuple_Check(t) && PyTuple_GET_SIZE(t) == 2) {
|
||||||
long mask;
|
long mask;
|
||||||
PyObject *pmask=NULL;
|
PyObject *pmask=NULL;
|
||||||
pmask = PyTuple_GET_ITEM(t, 0);
|
pmask = PyTuple_GET_ITEM(t, 0);
|
||||||
@ -461,14 +482,13 @@ _mysql_ResultObject_Initialize(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto cleanup;
|
fun2 = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Py_DECREF(t);
|
Py_DECREF(t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanup:
|
|
||||||
Py_DECREF(t);
|
Py_DECREF(t);
|
||||||
}
|
}
|
||||||
if (!fun2) fun2 = Py_None;
|
if (!fun2) fun2 = Py_None;
|
||||||
@ -478,6 +498,8 @@ _mysql_ResultObject_Initialize(
|
|||||||
}
|
}
|
||||||
PyTuple_SET_ITEM(self->converter, i, fun);
|
PyTuple_SET_ITEM(self->converter, i, fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_DECREF(conv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user