mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	Fixes issue1371 and reenables those tests.
Merge r58757 and r58758 from trunk. Undoes incorrect dbtables fix and errant strdup introduced as described below: r58757 | gregory.p.smith | 2007-11-01 14:08:14 -0700 (Thu, 01 Nov 2007) | 4 lines Fix bug introduced in revision 58385. Database keys could no longer have NULL bytes in them. Replace the errant strdup with a malloc+memcpy. Adds a unit test for the correct behavior. r58758 | gregory.p.smith | 2007-11-01 14:15:36 -0700 (Thu, 01 Nov 2007) | 3 lines Undo revision 58533 58534 fixes. Those were a workaround for a problem introduced by 58385.
This commit is contained in:
		
							parent
							
								
									48decfe740
								
							
						
					
					
						commit
						568065e9d1
					
				
					 3 changed files with 52 additions and 20 deletions
				
			
		|  | @ -362,12 +362,11 @@ class bsdTableDB : | ||||||
|         unique = 0 |         unique = 0 | ||||||
|         while not unique: |         while not unique: | ||||||
|             # Generate a random 64-bit row ID string |             # Generate a random 64-bit row ID string | ||||||
|             # (note: this code has <64 bits of randomness |             # (note: might have <64 bits of randomness | ||||||
|             # but it's plenty for our database id needs!) |             # but it's plenty for our database id needs!) | ||||||
|             # We must ensure that no null bytes are in the id value. |  | ||||||
|             blist = [] |             blist = [] | ||||||
|             for x in range(_rowid_str_len): |             for x in range(_rowid_str_len): | ||||||
|                 blist.append(random.randint(1,255)) |                 blist.append(random.randint(0,255)) | ||||||
|             newid = bytes(blist) |             newid = bytes(blist) | ||||||
| 
 | 
 | ||||||
|             # Guarantee uniqueness by adding this key to the database |             # Guarantee uniqueness by adding this key to the database | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ try: | ||||||
|     # For Pythons w/distutils pybsddb |     # For Pythons w/distutils pybsddb | ||||||
|     from bsddb3 import db, dbshelve, hashopen |     from bsddb3 import db, dbshelve, hashopen | ||||||
| except ImportError: | except ImportError: | ||||||
|     # For Python 2.3 |     # For the bundled bsddb | ||||||
|     from bsddb import db, dbshelve, hashopen |     from bsddb import db, dbshelve, hashopen | ||||||
| 
 | 
 | ||||||
| #---------------------------------------------------------------------- | #---------------------------------------------------------------------- | ||||||
|  | @ -28,10 +28,10 @@ class MiscTestCase(unittest.TestCase): | ||||||
|             pass |             pass | ||||||
|         shutil.rmtree(self.homeDir) |         shutil.rmtree(self.homeDir) | ||||||
| 
 | 
 | ||||||
| ##     def test01_badpointer(self): |     def test01_badpointer(self): | ||||||
| ##         dbs = dbshelve.open(self.filename) |         dbs = dbshelve.open(self.filename) | ||||||
| ##         dbs.close() |         dbs.close() | ||||||
| ##         self.assertRaises(db.DBError, dbs.get, "foo") |         self.assertRaises(db.DBError, dbs.get, b"foo") | ||||||
| 
 | 
 | ||||||
|     def test02_db_home(self): |     def test02_db_home(self): | ||||||
|         env = db.DBEnv() |         env = db.DBEnv() | ||||||
|  | @ -53,18 +53,37 @@ class MiscTestCase(unittest.TestCase): | ||||||
|     # The problem was that make_key_dbt() was not allocating a copy of |     # The problem was that make_key_dbt() was not allocating a copy of | ||||||
|     # string keys but FREE_DBT() was always being told to free it when the |     # string keys but FREE_DBT() was always being told to free it when the | ||||||
|     # database was opened with DB_THREAD. |     # database was opened with DB_THREAD. | ||||||
| ##     def test04_double_free_make_key_dbt(self): |     def test04_double_free_make_key_dbt(self): | ||||||
| ##         try: |         try: | ||||||
| ##             db1 = db.DB() |             db1 = db.DB() | ||||||
| ##             db1.open(self.filename, None, db.DB_BTREE, |             db1.open(self.filename, None, db.DB_BTREE, | ||||||
| ##                      db.DB_CREATE | db.DB_THREAD) |                      db.DB_CREATE | db.DB_THREAD) | ||||||
| 
 | 
 | ||||||
| ##             curs = db1.cursor() |             curs = db1.cursor() | ||||||
| ##             t = curs.get(b"/foo", db.DB_SET) |             t = curs.get(b"/foo", db.DB_SET) | ||||||
| ##             # double free happened during exit from DBC_get |             # double free happened during exit from DBC_get | ||||||
| ##         finally: |         finally: | ||||||
| ##             db1.close() |             db1.close() | ||||||
| ##             os.unlink(self.filename) |             os.unlink(self.filename) | ||||||
|  | 
 | ||||||
|  |     def test05_key_with_null_bytes(self): | ||||||
|  |         try: | ||||||
|  |             db1 = db.DB() | ||||||
|  |             db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE) | ||||||
|  |             db1[b'a'] = b'eh?' | ||||||
|  |             db1[b'a\x00'] = b'eh zed.' | ||||||
|  |             db1[b'a\x00a'] = b'eh zed eh?' | ||||||
|  |             db1[b'aaa'] = b'eh eh eh!' | ||||||
|  |             keys = db1.keys() | ||||||
|  |             keys.sort() | ||||||
|  |             self.assertEqual([b'a', b'a\x00', b'a\x00a', b'aaa'], keys) | ||||||
|  |             self.assertEqual(db1[b'a'], b'eh?') | ||||||
|  |             self.assertEqual(db1[b'a\x00'], b'eh zed.') | ||||||
|  |             self.assertEqual(db1[b'a\x00a'], b'eh zed eh?') | ||||||
|  |             self.assertEqual(db1[b'aaa'], b'eh eh eh!') | ||||||
|  |         finally: | ||||||
|  |             db1.close() | ||||||
|  |             os.unlink(self.filename) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #---------------------------------------------------------------------- | #---------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | @ -439,8 +439,22 @@ make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags, | ||||||
|         if ( !(view = _malloc_view(keyobj)) ) |         if ( !(view = _malloc_view(keyobj)) ) | ||||||
|             return 0; |             return 0; | ||||||
| 
 | 
 | ||||||
|         key->data = view->buf; |         /*
 | ||||||
|  |          * NOTE(gps): I don't like doing a data copy here, it seems | ||||||
|  |          * wasteful.  But without a clean way to tell FREE_DBT if it | ||||||
|  |          * should free key->data or not we have to.  Other places in | ||||||
|  |          * the code check for DB_THREAD and forceably set DBT_MALLOC | ||||||
|  |          * when we otherwise would leave flags 0 to indicate that. | ||||||
|  |          */ | ||||||
|         key->size = Py_SAFE_DOWNCAST(view->len, Py_ssize_t, u_int32_t); |         key->size = Py_SAFE_DOWNCAST(view->len, Py_ssize_t, u_int32_t); | ||||||
|  |         key->data = malloc(key->size); | ||||||
|  |         if (key->data == NULL) { | ||||||
|  |             PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed"); | ||||||
|  |             key->size = 0; | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |         memcpy(key->data, view->buf, key->size); | ||||||
|  |         key->flags = DB_DBT_REALLOC; | ||||||
|         *returned_view_p = view; |         *returned_view_p = view; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gregory P. Smith
						Gregory P. Smith