summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/bsddb/test/test_basics.py20
-rw-r--r--Modules/_bsddb.c42
2 files changed, 57 insertions, 5 deletions
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index 37f4d11..7524b35 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -604,6 +604,26 @@ class BasicTransactionTestCase(BasicTestCase):
assert num == 0, "truncate on empty DB returned nonzero (%s)" % `num`
txn.commit()
+ #----------------------------------------
+
+ def test08_TxnLateUse(self):
+ txn = self.env.txn_begin()
+ txn.abort()
+ try:
+ txn.abort()
+ except db.DBError, e:
+ pass
+ else:
+ raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception"
+
+ txn = self.env.txn_begin()
+ txn.commit()
+ try:
+ txn.commit()
+ except db.DBError, e:
+ pass
+ else:
+ raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
class BTreeTransactionTestCase(BasicTransactionTestCase):
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index 9bb339c..8b93af3 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -85,7 +85,7 @@
/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
-#define PY_BSDDB_VERSION "4.1.1"
+#define PY_BSDDB_VERSION "4.1.2"
static char *rcs_id = "$Id$";
@@ -465,6 +465,7 @@ static int makeDBError(int err)
}
if (errObj != NULL) {
+ /* FIXME this needs proper bounds checking on errTxt */
strcpy(errTxt, db_strerror(err));
if (_db_errmsg[0]) {
strcat(errTxt, " -- ");
@@ -3722,15 +3723,23 @@ static PyObject*
DBTxn_commit(DBTxnObject* self, PyObject* args)
{
int flags=0, err;
+ DB_TXN *txn;
if (!PyArg_ParseTuple(args, "|i:commit", &flags))
return NULL;
+ if (!self->txn) {
+ PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
+ "DBTxn must not be used after txn_commit or txn_abort"));
+ return NULL;
+ }
+ txn = self->txn;
+ self->txn = NULL; /* this DB_TXN is no longer valid after this call */
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
- err = self->txn->commit(self->txn, flags);
+ err = txn->commit(txn, flags);
#else
- err = txn_commit(self->txn, flags);
+ err = txn_commit(txn, flags);
#endif
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
@@ -3754,6 +3763,11 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
return NULL;
}
+ if (!self->txn) {
+ PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
+ "DBTxn must not be used after txn_commit or txn_abort"));
+ return NULL;
+ }
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
err = self->txn->prepare(self->txn, (u_int8_t*)gid);
@@ -3769,6 +3783,11 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
if (!PyArg_ParseTuple(args, ":prepare"))
return NULL;
+ if (!self->txn) {
+ PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
+ "DBTxn must not be used after txn_commit or txn_abort"));
+ return NULL;
+ }
MYDB_BEGIN_ALLOW_THREADS;
err = txn_prepare(self->txn);
MYDB_END_ALLOW_THREADS;
@@ -3782,15 +3801,23 @@ static PyObject*
DBTxn_abort(DBTxnObject* self, PyObject* args)
{
int err;
+ DB_TXN *txn;
if (!PyArg_ParseTuple(args, ":abort"))
return NULL;
+ if (!self->txn) {
+ PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
+ "DBTxn must not be used after txn_commit or txn_abort"));
+ return NULL;
+ }
+ txn = self->txn;
+ self->txn = NULL; /* this DB_TXN is no longer valid after this call */
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
- err = self->txn->abort(self->txn);
+ err = txn->abort(txn);
#else
- err = txn_abort(self->txn);
+ err = txn_abort(txn);
#endif
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
@@ -3806,6 +3833,11 @@ DBTxn_id(DBTxnObject* self, PyObject* args)
if (!PyArg_ParseTuple(args, ":id"))
return NULL;
+ if (!self->txn) {
+ PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
+ "DBTxn must not be used after txn_commit or txn_abort"));
+ return NULL;
+ }
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
id = self->txn->id(self->txn);