summaryrefslogtreecommitdiffstats
path: root/Modules/_bsddb.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_bsddb.c')
-rw-r--r--Modules/_bsddb.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index ef0c7f3..d569b7d 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -1713,6 +1713,7 @@ DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
PyObject* dataobj;
PyObject* retval = NULL;
DBT key, data;
+ void *orig_data;
DB_TXN *txn = NULL;
static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
@@ -1724,7 +1725,6 @@ DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
CHECK_DB_NOT_CLOSED(self);
if (!make_key_dbt(self, keyobj, &key, NULL))
return NULL;
- CLEAR_DBT(data);
if ( !make_dbt(dataobj, &data) ||
!checkTxnObj(txnobj, &txn) )
{
@@ -1733,13 +1733,12 @@ DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
}
flags |= DB_GET_BOTH;
+ orig_data = data.data;
if (CHECK_DBFLAG(self, DB_THREAD)) {
/* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
data.flags = DB_DBT_MALLOC;
- /* TODO: Is this flag needed? We're passing a data object that should
- match what's in the DB, so there should be no need to malloc.
- We run the risk of freeing something twice! Check this. */
}
MYDB_BEGIN_ALLOW_THREADS;
@@ -1753,8 +1752,13 @@ DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
retval = Py_None;
}
else if (!err) {
+ /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
retval = PyString_FromStringAndSize((char*)data.data, data.size);
- FREE_DBT(data); /* Only if retrieval was successful */
+
+ /* Even though the flags require DB_DBT_MALLOC, data is not always
+ allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
+ if (data.data != orig_data)
+ FREE_DBT(data);
}
FREE_DBT(key);