mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-23 01:16:34 +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>
|
||||
|
||||
* 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
|
||||
bit problems (all of them, kudos!)
|
||||
|
||||
|
|
|
@ -126,11 +126,12 @@ _psyco_connect_fill_exc(connectionObject *conn)
|
|||
static PyObject *
|
||||
psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||
{
|
||||
PyObject *conn, *factory = NULL;
|
||||
PyObject *conn = NULL, *factory = NULL;
|
||||
PyObject *pyport = NULL;
|
||||
|
||||
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 port[16];
|
||||
|
||||
|
@ -139,28 +140,31 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
|||
"connection_factory", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssOsssO", kwlist,
|
||||
&dsn, &database, &host, &pyport,
|
||||
&dsn_static, &database, &host, &pyport,
|
||||
&user, &password, &sslmode, &factory)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pyport && PyString_Check(pyport)) {
|
||||
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);
|
||||
Py_DECREF(pyint);
|
||||
}
|
||||
else if (pyport && PyInt_Check(pyport)) {
|
||||
iport = PyInt_AsLong(pyport);
|
||||
}
|
||||
else if (pyport != NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "port must be a string or int");
|
||||
return NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (iport > 0)
|
||||
PyOS_snprintf(port, 16, "%d", iport);
|
||||
|
||||
if (dsn == NULL) {
|
||||
if (dsn_static == NULL) {
|
||||
int l = 45; /* len("dbname= user= password= host= port= sslmode=\0") */
|
||||
|
||||
if (database) l += strlen(database);
|
||||
|
@ -170,43 +174,58 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
|||
if (password) l += strlen(password);
|
||||
if (sslmode) l += strlen(sslmode);
|
||||
|
||||
dsn = malloc(l*sizeof(char));
|
||||
if (dsn == NULL) {
|
||||
dsn_dynamic = malloc(l*sizeof(char));
|
||||
if (dsn_dynamic == NULL) {
|
||||
PyErr_SetString(InterfaceError, "dynamic dsn allocation failed");
|
||||
return NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
idsn = 0;
|
||||
if (database)
|
||||
idsn = _psyco_connect_fill_dsn(dsn, " dbname=", database, idsn);
|
||||
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " dbname=", database, idsn);
|
||||
if (host)
|
||||
idsn = _psyco_connect_fill_dsn(dsn, " host=", host, idsn);
|
||||
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " host=", host, idsn);
|
||||
if (iport > 0)
|
||||
idsn = _psyco_connect_fill_dsn(dsn, " port=", port, idsn);
|
||||
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " port=", port, idsn);
|
||||
if (user)
|
||||
idsn = _psyco_connect_fill_dsn(dsn, " user=", user, idsn);
|
||||
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " user=", user, idsn);
|
||||
if (password)
|
||||
idsn = _psyco_connect_fill_dsn(dsn, " password=", password, idsn);
|
||||
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " password=", password, idsn);
|
||||
if (sslmode)
|
||||
idsn = _psyco_connect_fill_dsn(dsn, " sslmode=", sslmode, idsn);
|
||||
idsn = _psyco_connect_fill_dsn(dsn_dynamic, " sslmode=", sslmode, idsn);
|
||||
|
||||
if (idsn > 0) {
|
||||
dsn[idsn] = '\0';
|
||||
memmove(dsn, &dsn[1], idsn);
|
||||
dsn_dynamic[idsn] = '\0';
|
||||
memmove(dsn_dynamic, &dsn_dynamic[1], idsn);
|
||||
}
|
||||
else {
|
||||
free(dsn);
|
||||
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);
|
||||
|
||||
/* allocate connection, fill with errors and return it */
|
||||
if (factory == NULL) factory = (PyObject *)&connectionType;
|
||||
conn = PyObject_CallFunction(factory, "s", dsn);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user