From e11d0d39ec3c9e3906f50d74d15eed1c01fa5fea Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Wed, 27 Nov 2013 12:42:57 +0000 Subject: [PATCH] Check connection type in lobject init Fixes ticket #187. --- NEWS | 2 ++ psycopg/lobject_type.c | 17 ++++++++++------- tests/test_lobject.py | 4 ++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 14b50512..ab2b3a5a 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ What's new in psycopg 2.5.2 (:ticket:`#170`). - Meaningful connection errors report a meaningful message, thanks to Alexey Borzenkov (:ticket:`#173`). +- Manually creating `lobject` with the wrong parameter doesn't segfault + (:ticket:`#187`). What's new in psycopg 2.5.1 diff --git a/psycopg/lobject_type.c b/psycopg/lobject_type.c index fee11c45..d5051570 100644 --- a/psycopg/lobject_type.c +++ b/psycopg/lobject_type.c @@ -355,10 +355,12 @@ lobject_dealloc(PyObject* obj) { lobjectObject *self = (lobjectObject *)obj; - if (lobject_close(self) < 0) - PyErr_Print(); - Py_XDECREF((PyObject*)self->conn); - PyMem_Free(self->smode); + if (self->conn) { /* if not, init failed */ + if (lobject_close(self) < 0) + PyErr_Print(); + Py_XDECREF((PyObject*)self->conn); + PyMem_Free(self->smode); + } Dprintf("lobject_dealloc: deleted lobject object at %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, Py_REFCNT(obj)); @@ -372,10 +374,11 @@ lobject_init(PyObject *obj, PyObject *args, PyObject *kwds) int oid = (int)InvalidOid, new_oid = (int)InvalidOid; const char *smode = ""; const char *new_file = NULL; - PyObject *conn; + PyObject *conn = NULL; - if (!PyArg_ParseTuple(args, "O|iziz", - &conn, &oid, &smode, &new_oid, &new_file)) + if (!PyArg_ParseTuple(args, "O!|iziz", + &connectionType, &conn, + &oid, &smode, &new_oid, &new_file)) return -1; return lobject_setup((lobjectObject *)obj, diff --git a/tests/test_lobject.py b/tests/test_lobject.py index 83e9e73c..e62e0d85 100755 --- a/tests/test_lobject.py +++ b/tests/test_lobject.py @@ -77,6 +77,10 @@ class LargeObjectTests(LargeObjectTestCase): self.assertNotEqual(lo, None) self.assertEqual(lo.mode[0], "w") + def test_connection_needed(self): + self.assertRaises(TypeError, + psycopg2.extensions.lobject, []) + def test_open_non_existent(self): # By creating then removing a large object, we get an Oid that # should be unused.