mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00
bugfix: disallow use of DB_TXN after commit() or abort(), prevents a
coredump or segmentation violation. Sourceforge patch ID 664896: http://sourceforge.net/tracker/index.php?func=detail&aid=664896&group_id=13900&atid=313900 The bug was reported on the pybsddb-users mailing list.
This commit is contained in:
parent
5ec186b1cb
commit
c25fd3fb48
2 changed files with 57 additions and 5 deletions
|
@ -604,6 +604,26 @@ class BasicTransactionTestCase(BasicTestCase):
|
||||||
assert num == 0, "truncate on empty DB returned nonzero (%s)" % `num`
|
assert num == 0, "truncate on empty DB returned nonzero (%s)" % `num`
|
||||||
txn.commit()
|
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):
|
class BTreeTransactionTestCase(BasicTransactionTestCase):
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
|
/* 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 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$";
|
static char *rcs_id = "$Id$";
|
||||||
|
|
||||||
|
|
||||||
|
@ -465,6 +465,7 @@ static int makeDBError(int err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errObj != NULL) {
|
if (errObj != NULL) {
|
||||||
|
/* FIXME this needs proper bounds checking on errTxt */
|
||||||
strcpy(errTxt, db_strerror(err));
|
strcpy(errTxt, db_strerror(err));
|
||||||
if (_db_errmsg[0]) {
|
if (_db_errmsg[0]) {
|
||||||
strcat(errTxt, " -- ");
|
strcat(errTxt, " -- ");
|
||||||
|
@ -3722,15 +3723,23 @@ static PyObject*
|
||||||
DBTxn_commit(DBTxnObject* self, PyObject* args)
|
DBTxn_commit(DBTxnObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
int flags=0, err;
|
int flags=0, err;
|
||||||
|
DB_TXN *txn;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "|i:commit", &flags))
|
if (!PyArg_ParseTuple(args, "|i:commit", &flags))
|
||||||
return NULL;
|
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;
|
MYDB_BEGIN_ALLOW_THREADS;
|
||||||
#if (DBVER >= 40)
|
#if (DBVER >= 40)
|
||||||
err = self->txn->commit(self->txn, flags);
|
err = txn->commit(txn, flags);
|
||||||
#else
|
#else
|
||||||
err = txn_commit(self->txn, flags);
|
err = txn_commit(txn, flags);
|
||||||
#endif
|
#endif
|
||||||
MYDB_END_ALLOW_THREADS;
|
MYDB_END_ALLOW_THREADS;
|
||||||
RETURN_IF_ERR();
|
RETURN_IF_ERR();
|
||||||
|
@ -3754,6 +3763,11 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
|
||||||
return NULL;
|
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;
|
MYDB_BEGIN_ALLOW_THREADS;
|
||||||
#if (DBVER >= 40)
|
#if (DBVER >= 40)
|
||||||
err = self->txn->prepare(self->txn, (u_int8_t*)gid);
|
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"))
|
if (!PyArg_ParseTuple(args, ":prepare"))
|
||||||
return NULL;
|
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;
|
MYDB_BEGIN_ALLOW_THREADS;
|
||||||
err = txn_prepare(self->txn);
|
err = txn_prepare(self->txn);
|
||||||
MYDB_END_ALLOW_THREADS;
|
MYDB_END_ALLOW_THREADS;
|
||||||
|
@ -3782,15 +3801,23 @@ static PyObject*
|
||||||
DBTxn_abort(DBTxnObject* self, PyObject* args)
|
DBTxn_abort(DBTxnObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
DB_TXN *txn;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, ":abort"))
|
if (!PyArg_ParseTuple(args, ":abort"))
|
||||||
return NULL;
|
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;
|
MYDB_BEGIN_ALLOW_THREADS;
|
||||||
#if (DBVER >= 40)
|
#if (DBVER >= 40)
|
||||||
err = self->txn->abort(self->txn);
|
err = txn->abort(txn);
|
||||||
#else
|
#else
|
||||||
err = txn_abort(self->txn);
|
err = txn_abort(txn);
|
||||||
#endif
|
#endif
|
||||||
MYDB_END_ALLOW_THREADS;
|
MYDB_END_ALLOW_THREADS;
|
||||||
RETURN_IF_ERR();
|
RETURN_IF_ERR();
|
||||||
|
@ -3806,6 +3833,11 @@ DBTxn_id(DBTxnObject* self, PyObject* args)
|
||||||
if (!PyArg_ParseTuple(args, ":id"))
|
if (!PyArg_ParseTuple(args, ":id"))
|
||||||
return NULL;
|
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;
|
MYDB_BEGIN_ALLOW_THREADS;
|
||||||
#if (DBVER >= 40)
|
#if (DBVER >= 40)
|
||||||
id = self->txn->id(self->txn);
|
id = self->txn->id(self->txn);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue