]> granicus.if.org Git - python/commitdiff
bugfix: do not double-close DB cursor during deallocation when the
authorGregory P. Smith <greg@mad-scientist.com>
Fri, 17 Jan 2003 08:42:50 +0000 (08:42 +0000)
committerGregory P. Smith <greg@mad-scientist.com>
Fri, 17 Jan 2003 08:42:50 +0000 (08:42 +0000)
        underlying DB has already been closed (and thus all of its cursors).
        This fixes a potential segfault.
        SF pybsddb bug id 667343
bugfix: close the DB object when raising an exception due to an error
        during DB.open.  This prevents an exception when closing the
        environment about not all databases being closed.
        SF pybsddb bug id 667340

Lib/bsddb/test/test_basics.py
Modules/_bsddb.c

index 7524b35eaf6a1ad34b78de98a528707cd199f1b5..25cc77cafc7ac2838373d1d6ade8e902edc2d08e 100644 (file)
@@ -398,6 +398,18 @@ class BasicTestCase(unittest.TestCase):
                 self.fail("no exception raised when using a buggy cursor's"
                           "%s method" % method)
 
+        #
+        # free cursor referencing a closed database, it should not barf:
+        #
+        oldcursor = self.d.cursor(txn=txn)
+        self.d.close()
+
+        # this would originally cause a segfault when the cursor for a
+        # closed database was cleaned up.  it should not anymore.
+        # SF pybsddb bug id 667343
+        del oldcursor
+
+
     #----------------------------------------
 
     def test04_PartialGetAndPut(self):
index 9561d2805ec725719f161836c69822f86033e4f9..396a3cc72eaeee9720a5150895d1804c06847f29 100644 (file)
@@ -746,7 +746,8 @@ DBCursor_dealloc(DBCursorObject* self)
     int err;
     if (self->dbc != NULL) {
         MYDB_BEGIN_ALLOW_THREADS;
-        err = self->dbc->c_close(self->dbc);
+       if (self->mydb->db != NULL)
+            err = self->dbc->c_close(self->dbc);
         self->dbc = NULL;
         MYDB_END_ALLOW_THREADS;
     }
@@ -1623,6 +1624,7 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
 #endif
     MYDB_END_ALLOW_THREADS;
     if (makeDBError(err)) {
+        self->db->close(self->db, 0);
         self->db = NULL;
         return NULL;
     }