mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +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 @@ def test07_TxnTruncate(self): | |||
|         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): | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gregory P. Smith
						Gregory P. Smith