mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-12 07:10:33 +03:00
Fixed segfault in large object close.
Check that the connection is not closed/faulty before attempting lo_close.
This commit is contained in:
parent
38641b93ea
commit
935c25730a
4
NEWS-2.3
4
NEWS-2.3
|
@ -7,12 +7,14 @@ What's new in psycopg 2.3.3
|
||||||
into Python tuples/namedtuples.
|
into Python tuples/namedtuples.
|
||||||
- The build script refuses to guess values if pg_config is not found.
|
- The build script refuses to guess values if pg_config is not found.
|
||||||
- Connections and cursors are weakly referenceable.
|
- Connections and cursors are weakly referenceable.
|
||||||
- Fixed several reference leaks in less common code paths.
|
|
||||||
|
|
||||||
* Bug fixes:
|
* Bug fixes:
|
||||||
|
|
||||||
- Fixed adaptation of None in composite types (ticket #26). Bug report by
|
- Fixed adaptation of None in composite types (ticket #26). Bug report by
|
||||||
Karsten Hilbert.
|
Karsten Hilbert.
|
||||||
|
- Fixed several reference leaks in less common code paths.
|
||||||
|
- Fixed segfault when a large object is closed and its connection no more
|
||||||
|
available.
|
||||||
|
|
||||||
|
|
||||||
What's new in psycopg 2.3.2
|
What's new in psycopg 2.3.2
|
||||||
|
|
|
@ -129,6 +129,21 @@ lobject_close_locked(lobjectObject *self, char **error)
|
||||||
{
|
{
|
||||||
int retvalue;
|
int retvalue;
|
||||||
|
|
||||||
|
Dprintf("lobject_close_locked: conn->closed %ld", self->conn->closed);
|
||||||
|
switch (self->conn->closed) {
|
||||||
|
case 0:
|
||||||
|
/* Connection is open, go ahead */
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* Connection is closed, return a success */
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_SetString(OperationalError, "the connection is broken");
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT ||
|
if (self->conn->isolation_level == ISOLATION_LEVEL_AUTOCOMMIT ||
|
||||||
self->conn->mark != self->mark ||
|
self->conn->mark != self->mark ||
|
||||||
self->fd == -1)
|
self->fd == -1)
|
||||||
|
|
|
@ -60,6 +60,10 @@ class LargeObjectMixin(object):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if self.tmpdir:
|
if self.tmpdir:
|
||||||
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
||||||
|
|
||||||
|
if self.conn.closed:
|
||||||
|
return
|
||||||
|
|
||||||
if self.lo_oid is not None:
|
if self.lo_oid is not None:
|
||||||
self.conn.rollback()
|
self.conn.rollback()
|
||||||
try:
|
try:
|
||||||
|
@ -106,6 +110,11 @@ class LargeObjectTests(LargeObjectMixin, unittest.TestCase):
|
||||||
self.assertEqual(lo2.oid, lo.oid)
|
self.assertEqual(lo2.oid, lo.oid)
|
||||||
self.assertEqual(lo2.closed, True)
|
self.assertEqual(lo2.closed, True)
|
||||||
|
|
||||||
|
def test_close_connection_gone(self):
|
||||||
|
lo = self.conn.lobject()
|
||||||
|
self.conn.close()
|
||||||
|
lo.close()
|
||||||
|
|
||||||
def test_create_with_oid(self):
|
def test_create_with_oid(self):
|
||||||
# Create and delete a large object to get an unused Oid.
|
# Create and delete a large object to get an unused Oid.
|
||||||
lo = self.conn.lobject()
|
lo = self.conn.lobject()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user