mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-17 01:20:32 +03:00
Fixed mem and ref leak in connect().
This commit is contained in:
parent
e5829292cd
commit
d6f2aa27b7
|
@ -1,5 +1,8 @@
|
||||||
2007-04-10 Federico Di Gregorio <fog@initd.org>
|
2007-04-10 Federico Di Gregorio <fog@initd.org>
|
||||||
|
|
||||||
|
* Applied patch from David Rushby to fix mem and ref leaks in
|
||||||
|
psycopg2.connect().
|
||||||
|
|
||||||
* Applied super-patch from David Rushby to fix Python 2.5 and 64
|
* Applied super-patch from David Rushby to fix Python 2.5 and 64
|
||||||
bit problems (all of them, kudos!)
|
bit problems (all of them, kudos!)
|
||||||
|
|
||||||
|
|
|
@ -126,11 +126,12 @@ _psyco_connect_fill_exc(connectionObject *conn)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
{
|
{
|
||||||
PyObject *conn, *factory = NULL;
|
PyObject *conn = NULL, *factory = NULL;
|
||||||
PyObject *pyport = NULL;
|
PyObject *pyport = NULL;
|
||||||
|
|
||||||
int idsn=-1, iport=-1;
|
int idsn=-1, iport=-1;
|
||||||
char *dsn=NULL, *database=NULL, *user=NULL, *password=NULL;
|
char *dsn_static=NULL, *dsn_dynamic=NULL;
|
||||||
|
char *database=NULL, *user=NULL, *password=NULL;
|
||||||
char *host=NULL, *sslmode=NULL;
|
char *host=NULL, *sslmode=NULL;
|
||||||
char port[16];
|
char port[16];
|
||||||
|
|
||||||
|
@ -139,28 +140,31 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
"connection_factory", NULL};
|
"connection_factory", NULL};
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssOsssO", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssOsssO", kwlist,
|
||||||
&dsn, &database, &host, &pyport,
|
&dsn_static, &database, &host, &pyport,
|
||||||
&user, &password, &sslmode, &factory)) {
|
&user, &password, &sslmode, &factory)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pyport && PyString_Check(pyport)) {
|
if (pyport && PyString_Check(pyport)) {
|
||||||
PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10);
|
PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10);
|
||||||
if (!pyint) return NULL;
|
if (!pyint) goto fail;
|
||||||
|
/* Must use PyInt_AsLong rather than PyInt_AS_LONG, because
|
||||||
|
* PyInt_FromString can return a PyLongObject: */
|
||||||
iport = PyInt_AsLong(pyint);
|
iport = PyInt_AsLong(pyint);
|
||||||
|
Py_DECREF(pyint);
|
||||||
}
|
}
|
||||||
else if (pyport && PyInt_Check(pyport)) {
|
else if (pyport && PyInt_Check(pyport)) {
|
||||||
iport = PyInt_AsLong(pyport);
|
iport = PyInt_AsLong(pyport);
|
||||||
}
|
}
|
||||||
else if (pyport != NULL) {
|
else if (pyport != NULL) {
|
||||||
PyErr_SetString(PyExc_TypeError, "port must be a string or int");
|
PyErr_SetString(PyExc_TypeError, "port must be a string or int");
|
||||||
return NULL;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iport > 0)
|
if (iport > 0)
|
||||||
PyOS_snprintf(port, 16, "%d", iport);
|
PyOS_snprintf(port, 16, "%d", iport);
|
||||||
|
|
||||||
if (dsn == NULL) {
|
if (dsn_static == NULL) {
|
||||||
int l = 45; /* len("dbname= user= password= host= port= sslmode=\0") */
|
int l = 45; /* len("dbname= user= password= host= port= sslmode=\0") */
|
||||||
|
|
||||||
if (database) l += strlen(database);
|
if (database) l += strlen(database);
|
||||||
|
@ -170,43 +174,58 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
if (password) l += strlen(password);
|
if (password) l += strlen(password);
|
||||||
if (sslmode) l += strlen(sslmode);
|
if (sslmode) l += strlen(sslmode);
|
||||||
|
|
||||||
dsn = malloc(l*sizeof(char));
|
dsn_dynamic = malloc(l*sizeof(char));
|
||||||
if (dsn == NULL) {
|
if (dsn_dynamic == NULL) {
|
||||||
PyErr_SetString(InterfaceError, "dynamic dsn allocation failed");
|
PyErr_SetString(InterfaceError, "dynamic dsn allocation failed");
|
||||||
return NULL;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
idsn = 0;
|
idsn = 0;
|
||||||
if (database)
|
if (database)
|
||||||
idsn = _psyco_connect_fill_dsn(dsn, " dbname=", database, idsn);
|
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " dbname=", database, idsn);
|
||||||
if (host)
|
if (host)
|
||||||
idsn = _psyco_connect_fill_dsn(dsn, " host=", host, idsn);
|
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " host=", host, idsn);
|
||||||
if (iport > 0)
|
if (iport > 0)
|
||||||
idsn = _psyco_connect_fill_dsn(dsn, " port=", port, idsn);
|
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " port=", port, idsn);
|
||||||
if (user)
|
if (user)
|
||||||
idsn = _psyco_connect_fill_dsn(dsn, " user=", user, idsn);
|
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " user=", user, idsn);
|
||||||
if (password)
|
if (password)
|
||||||
idsn = _psyco_connect_fill_dsn(dsn, " password=", password, idsn);
|
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " password=", password, idsn);
|
||||||
if (sslmode)
|
if (sslmode)
|
||||||
idsn = _psyco_connect_fill_dsn(dsn, " sslmode=", sslmode, idsn);
|
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " sslmode=", sslmode, idsn);
|
||||||
|
|
||||||
if (idsn > 0) {
|
if (idsn > 0) {
|
||||||
dsn[idsn] = '\0';
|
dsn_dynamic[idsn] = '\0';
|
||||||
memmove(dsn, &dsn[1], idsn);
|
memmove(dsn_dynamic, &dsn_dynamic[1], idsn);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free(dsn);
|
|
||||||
PyErr_SetString(InterfaceError, "missing dsn and no parameters");
|
PyErr_SetString(InterfaceError, "missing dsn and no parameters");
|
||||||
return NULL;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *dsn = (dsn_static != NULL ? dsn_static : dsn_dynamic);
|
||||||
Dprintf("psyco_connect: dsn = '%s'", dsn);
|
Dprintf("psyco_connect: dsn = '%s'", dsn);
|
||||||
|
|
||||||
/* allocate connection, fill with errors and return it */
|
/* allocate connection, fill with errors and return it */
|
||||||
if (factory == NULL) factory = (PyObject *)&connectionType;
|
if (factory == NULL) factory = (PyObject *)&connectionType;
|
||||||
conn = PyObject_CallFunction(factory, "s", dsn);
|
conn = PyObject_CallFunction(factory, "s", dsn);
|
||||||
if (conn) _psyco_connect_fill_exc((connectionObject*)conn);
|
if (conn) _psyco_connect_fill_exc((connectionObject*)conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
fail:
|
||||||
|
assert (PyErr_Occurred());
|
||||||
|
if (conn != NULL) {
|
||||||
|
Py_DECREF(conn);
|
||||||
|
conn = NULL;
|
||||||
|
}
|
||||||
|
/* Fall through to cleanup: */
|
||||||
|
cleanup:
|
||||||
|
if (dsn_dynamic != NULL) {
|
||||||
|
free(dsn_dynamic);
|
||||||
|
}
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user