summaryrefslogtreecommitdiff
path: root/MySQLdb
diff options
context:
space:
mode:
authorAndré Malo <ndparker@users.sf.net>2012-10-03 13:17:35 -0400
committerfarcepest <farcepest@gmail.com>2012-10-03 13:17:35 -0400
commitc05a2c6a50bb57655165cf95279d5501226ce369 (patch)
tree6055f8667d0de6dcd27c2dc938a7bc03736ffffe /MySQLdb
parent1c33baf352a2e4ec7de41cfdfb38ca62b5b3ee5b (diff)
downloadmysqldb1-c05a2c6a50bb57655165cf95279d5501226ce369.tar.gz
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/
Diffstat (limited to 'MySQLdb')
-rw-r--r--MySQLdb/_mysql.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/MySQLdb/_mysql.c b/MySQLdb/_mysql.c
index 63e990f..b222663 100644
--- a/MySQLdb/_mysql.c
+++ b/MySQLdb/_mysql.c
@@ -407,8 +407,13 @@ _mysql_ResultObject_Initialize(
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist,
&conn, &use, &conv))
return -1;
- if (!conv) conv = PyDict_New();
- if (!conv) return -1;
+ if (!conv) {
+ if (!(conv = PyDict_New()))
+ return -1;
+ }
+ else
+ Py_INCREF(conv);
+
self->conn = (PyObject *) conn;
Py_INCREF(conn);
self->use = use;
@@ -425,31 +430,47 @@ _mysql_ResultObject_Initialize(
return -1;
}
self->converter = PyTuple_New(0);
+ Py_DECREF(conv);
return 0;
}
n = mysql_num_fields(result);
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);
for (i=0; i<n; i++) {
PyObject *tmp, *fun;
tmp = PyInt_FromLong((long) fields[i].type);
- if (!tmp) return -1;
+ if (!tmp) {
+ Py_DECREF(conv);
+ return -1;
+ }
fun = PyObject_GetItem(conv, tmp);
Py_DECREF(tmp);
if (!fun) {
- PyErr_Clear();
+ if (PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
+ Py_DECREF(conv);
+ return -1;
+ }
+ PyErr_Clear();
+ }
fun = Py_None;
Py_INCREF(Py_None);
}
- if (PySequence_Check(fun)) {
+ else if (PySequence_Check(fun)) {
int j, n2=PySequence_Size(fun);
PyObject *fun2=NULL;
for (j=0; j<n2; j++) {
PyObject *t = PySequence_GetItem(fun, j);
- if (!t) continue;
- if (!PyTuple_Check(t)) goto cleanup;
- if (PyTuple_GET_SIZE(t) == 2) {
+ if (!t) {
+ Py_DECREF(fun);
+ Py_DECREF(conv);
+ return -1;
+ }
+ if (PyTuple_Check(t) && PyTuple_GET_SIZE(t) == 2) {
long mask;
PyObject *pmask=NULL;
pmask = PyTuple_GET_ITEM(t, 0);
@@ -461,14 +482,13 @@ _mysql_ResultObject_Initialize(
break;
}
else {
- goto cleanup;
+ fun2 = NULL;
}
} else {
Py_DECREF(t);
break;
}
}
- cleanup:
Py_DECREF(t);
}
if (!fun2) fun2 = Py_None;
@@ -478,6 +498,8 @@ _mysql_ResultObject_Initialize(
}
PyTuple_SET_ITEM(self->converter, i, fun);
}
+
+ Py_DECREF(conv);
return 0;
}