mirror of https://github.com/python/cpython
Fix a double free when positioning a database cursor to a non-existant
string key (and probably a few other situations with string keys). This was reported with a patch as pybsddb sourceforge bug 1708868 by jjjhhhlll at gmail.
This commit is contained in:
parent
392505391e
commit
10bed54ae2
|
@ -53,6 +53,26 @@ class MiscTestCase(unittest.TestCase):
|
||||||
rp = repr(db)
|
rp = repr(db)
|
||||||
self.assertEquals(rp, "{}")
|
self.assertEquals(rp, "{}")
|
||||||
|
|
||||||
|
# http://sourceforge.net/tracker/index.php?func=detail&aid=1708868&group_id=13900&atid=313900
|
||||||
|
#
|
||||||
|
# See the bug report for details.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# database was opened with DB_THREAD.
|
||||||
|
def test04_double_free_make_key_dbt(self):
|
||||||
|
try:
|
||||||
|
db1 = db.DB()
|
||||||
|
db1.open(self.filename, None, db.DB_BTREE,
|
||||||
|
db.DB_CREATE | db.DB_THREAD)
|
||||||
|
|
||||||
|
curs = db1.cursor()
|
||||||
|
t = curs.get("/foo", db.DB_SET)
|
||||||
|
# double free happened during exit from DBC_get
|
||||||
|
finally:
|
||||||
|
db1.close()
|
||||||
|
os.unlink(self.filename)
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,19 @@ make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
key->data = PyString_AS_STRING(keyobj);
|
/*
|
||||||
|
* 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->data = strdup(PyString_AS_STRING(keyobj));
|
||||||
|
if (key->data == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
key->flags = DB_DBT_REALLOC;
|
||||||
key->size = PyString_GET_SIZE(keyobj);
|
key->size = PyString_GET_SIZE(keyobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue