@@ -779,6 +779,7 @@ newDBObject(DBEnvObject* arg, int flags)
779
779
Py_DECREF (self -> myenvobj );
780
780
self -> myenvobj = NULL ;
781
781
}
782
+ PyObject_Del (self );
782
783
self = NULL ;
783
784
}
784
785
return self ;
@@ -895,6 +896,7 @@ newDBEnvObject(int flags)
895
896
err = db_env_create (& self -> db_env , flags );
896
897
MYDB_END_ALLOW_THREADS ;
897
898
if (makeDBError (err )) {
899
+ PyObject_Del (self );
898
900
self = NULL ;
899
901
}
900
902
else {
@@ -1001,6 +1003,7 @@ newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1001
1003
#endif
1002
1004
MYDB_END_ALLOW_THREADS ;
1003
1005
if (makeDBError (err )) {
1006
+ PyObject_Del (self );
1004
1007
self = NULL ;
1005
1008
}
1006
1009
@@ -1067,26 +1070,20 @@ _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1067
1070
DBObject * secondaryDB = (DBObject * )db -> app_private ;
1068
1071
PyObject * callback = secondaryDB -> associateCallback ;
1069
1072
int type = secondaryDB -> primaryDBType ;
1070
- PyObject * key ;
1071
- PyObject * data ;
1072
1073
PyObject * args ;
1073
1074
PyObject * result = NULL ;
1074
1075
1075
1076
1076
1077
if (callback != NULL ) {
1077
1078
MYDB_BEGIN_BLOCK_THREADS ;
1078
1079
1079
- if (type == DB_RECNO || type == DB_QUEUE ) {
1080
- key = PyInt_FromLong ( * ((db_recno_t * )priKey -> data ));
1081
- }
1082
- else {
1083
- key = PyString_FromStringAndSize (priKey -> data , priKey -> size );
1084
- }
1085
- data = PyString_FromStringAndSize (priData -> data , priData -> size );
1086
- args = PyTuple_New (2 );
1080
+ if (type == DB_RECNO || type == DB_QUEUE )
1081
+ args = Py_BuildValue ("(ls#)" , * ((db_recno_t * )priKey -> data ),
1082
+ priData -> data , priData -> size );
1083
+ else
1084
+ args = Py_BuildValue ("(s#s#)" , priKey -> data , priKey -> size ,
1085
+ priData -> data , priData -> size );
1087
1086
if (args != NULL ) {
1088
- PyTuple_SET_ITEM (args , 0 , key ); /* steals reference */
1089
- PyTuple_SET_ITEM (args , 1 , data ); /* steals reference */
1090
1087
result = PyEval_CallObject (callback , args );
1091
1088
}
1092
1089
if (args == NULL || result == NULL ) {
@@ -1130,10 +1127,8 @@ _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1130
1127
PyErr_Print ();
1131
1128
}
1132
1129
1133
- Py_DECREF (args );
1134
- if (result ) {
1135
- Py_DECREF (result );
1136
- }
1130
+ Py_XDECREF (args );
1131
+ Py_XDECREF (result );
1137
1132
1138
1133
MYDB_END_BLOCK_THREADS ;
1139
1134
}
@@ -1187,7 +1182,7 @@ DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1187
1182
1188
1183
/* Save a reference to the callback in the secondary DB. */
1189
1184
Py_XDECREF (secondaryDB -> associateCallback );
1190
- Py_INCREF (callback );
1185
+ Py_XINCREF (callback );
1191
1186
secondaryDB -> associateCallback = callback ;
1192
1187
secondaryDB -> primaryDBType = _DB_get_type (self );
1193
1188
@@ -1542,6 +1537,7 @@ DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
1542
1537
#else
1543
1538
retval = Py_BuildValue ("OOO" , keyObj , pkeyObj , dataObj );
1544
1539
#endif
1540
+ Py_DECREF (keyObj );
1545
1541
}
1546
1542
else /* return just the pkey and data */
1547
1543
{
@@ -1551,6 +1547,8 @@ DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
1551
1547
retval = Py_BuildValue ("OO" , pkeyObj , dataObj );
1552
1548
#endif
1553
1549
}
1550
+ Py_DECREF (dataObj );
1551
+ Py_DECREF (pkeyObj );
1554
1552
FREE_DBT (pkey );
1555
1553
FREE_DBT (data );
1556
1554
}
@@ -1733,6 +1731,10 @@ DB_join(DBObject* self, PyObject* args)
1733
1731
cursors [length ] = NULL ;
1734
1732
for (x = 0 ; x < length ; x ++ ) {
1735
1733
PyObject * item = PySequence_GetItem (cursorsObj , x );
1734
+ if (item == NULL ) {
1735
+ free (cursors );
1736
+ return NULL ;
1737
+ }
1736
1738
if (!DBCursorObject_Check (item )) {
1737
1739
PyErr_SetString (PyExc_TypeError ,
1738
1740
"Sequence of DBCursor objects expected" );
@@ -1843,8 +1845,10 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
1843
1845
#endif
1844
1846
1845
1847
if (NULL == self -> db ) {
1846
- PyErr_SetObject (DBError , Py_BuildValue ("(is)" , 0 ,
1847
- "Cannot call open() twice for DB object" ));
1848
+ PyObject * t = Py_BuildValue ("(is)" , 0 ,
1849
+ "Cannot call open() twice for DB object" );
1850
+ PyErr_SetObject (DBError , t );
1851
+ Py_DECREF (t );
1848
1852
return NULL ;
1849
1853
}
1850
1854
@@ -2014,8 +2018,6 @@ _db_compareCallback(DB* db,
2014
2018
int res = 0 ;
2015
2019
PyObject * args ;
2016
2020
PyObject * result ;
2017
- PyObject * leftObject ;
2018
- PyObject * rightObject ;
2019
2021
DBObject * self = (DBObject * )db -> app_private ;
2020
2022
2021
2023
if (self == NULL || self -> btCompareCallback == NULL ) {
@@ -2031,14 +2033,11 @@ _db_compareCallback(DB* db,
2031
2033
} else {
2032
2034
MYDB_BEGIN_BLOCK_THREADS ;
2033
2035
2034
- leftObject = PyString_FromStringAndSize (leftKey -> data , leftKey -> size );
2035
- rightObject = PyString_FromStringAndSize (rightKey -> data , rightKey -> size );
2036
-
2037
- args = PyTuple_New (2 );
2036
+ args = Py_BuildValue ("s#s#" , leftKey -> data , leftKey -> size ,
2037
+ rightKey -> data , rightKey -> size );
2038
2038
if (args != NULL ) {
2039
+ /* XXX(twouters) I highly doubt this INCREF is correct */
2039
2040
Py_INCREF (self );
2040
- PyTuple_SET_ITEM (args , 0 , leftObject ); /* steals reference */
2041
- PyTuple_SET_ITEM (args , 1 , rightObject ); /* steals reference */
2042
2041
result = PyEval_CallObject (self -> btCompareCallback , args );
2043
2042
}
2044
2043
if (args == NULL || result == NULL ) {
@@ -2055,7 +2054,7 @@ _db_compareCallback(DB* db,
2055
2054
res = _default_cmp (leftKey , rightKey );
2056
2055
}
2057
2056
2058
- Py_DECREF (args );
2057
+ Py_XDECREF (args );
2059
2058
Py_XDECREF (result );
2060
2059
2061
2060
MYDB_END_BLOCK_THREADS ;
@@ -2068,7 +2067,7 @@ DB_set_bt_compare(DBObject* self, PyObject* args)
2068
2067
{
2069
2068
int err ;
2070
2069
PyObject * comparator ;
2071
- PyObject * tuple , * emptyStr , * result ;
2070
+ PyObject * tuple , * result ;
2072
2071
2073
2072
if (!PyArg_ParseTuple (args , "O:set_bt_compare" , & comparator ))
2074
2073
return NULL ;
@@ -2085,17 +2084,12 @@ DB_set_bt_compare(DBObject* self, PyObject* args)
2085
2084
* string objects here. verify that it returns an int (0).
2086
2085
* err if not.
2087
2086
*/
2088
- tuple = PyTuple_New (2 );
2089
- emptyStr = PyString_FromStringAndSize (NULL , 0 );
2090
- if (tuple == NULL || emptyStr == NULL )
2091
- return NULL ;
2092
-
2093
- Py_INCREF (emptyStr ); /* now we have two references */
2094
- PyTuple_SET_ITEM (tuple , 0 , emptyStr ); /* steals reference */
2095
- PyTuple_SET_ITEM (tuple , 1 , emptyStr ); /* steals reference */
2087
+ tuple = Py_BuildValue ("(ss)" , "" , "" );
2096
2088
result = PyEval_CallObject (comparator , tuple );
2097
2089
Py_DECREF (tuple );
2098
- if (result == NULL || !PyInt_Check (result )) {
2090
+ if (result == NULL )
2091
+ return NULL ;
2092
+ if (!PyInt_Check (result )) {
2099
2093
PyErr_SetString (PyExc_TypeError ,
2100
2094
"callback MUST return an int" );
2101
2095
return NULL ;
@@ -2104,6 +2098,7 @@ DB_set_bt_compare(DBObject* self, PyObject* args)
2104
2098
"callback failed to return 0 on two empty strings" );
2105
2099
return NULL ;
2106
2100
}
2101
+ Py_DECREF (result );
2107
2102
2108
2103
/* We don't accept multiple set_bt_compare operations, in order to
2109
2104
* simplify the code. This would have no real use, as one cannot
@@ -2122,9 +2117,7 @@ DB_set_bt_compare(DBObject* self, PyObject* args)
2122
2117
PyEval_InitThreads ();
2123
2118
#endif
2124
2119
2125
- err = self -> db -> set_bt_compare (self -> db ,
2126
- (comparator != NULL ?
2127
- _db_compareCallback : NULL ));
2120
+ err = self -> db -> set_bt_compare (self -> db , _db_compareCallback );
2128
2121
2129
2122
if (err ) {
2130
2123
/* restore the old state in case of error */
@@ -2621,8 +2614,9 @@ Py_ssize_t DB_length(DBObject* self)
2621
2614
void * sp ;
2622
2615
2623
2616
if (self -> db == NULL ) {
2624
- PyErr_SetObject (DBError ,
2625
- Py_BuildValue ("(is)" , 0 , "DB object has been closed" ));
2617
+ PyObject * t = Py_BuildValue ("(is)" , 0 , "DB object has been closed" );
2618
+ PyErr_SetObject (DBError , t );
2619
+ Py_DECREF (t );
2626
2620
return -1 ;
2627
2621
}
2628
2622
@@ -2698,8 +2692,9 @@ DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
2698
2692
int flags = 0 ;
2699
2693
2700
2694
if (self -> db == NULL ) {
2701
- PyErr_SetObject (DBError ,
2702
- Py_BuildValue ("(is)" , 0 , "DB object has been closed" ));
2695
+ PyObject * t = Py_BuildValue ("(is)" , 0 , "DB object has been closed" );
2696
+ PyErr_SetObject (DBError , t );
2697
+ Py_DECREF (t );
2703
2698
return -1 ;
2704
2699
}
2705
2700
@@ -2798,16 +2793,17 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
2798
2793
return NULL ;
2799
2794
2800
2795
list = PyList_New (0 );
2801
- if (list == NULL ) {
2802
- PyErr_SetString (PyExc_MemoryError , "PyList_New failed" );
2796
+ if (list == NULL )
2803
2797
return NULL ;
2804
- }
2805
2798
2806
2799
/* get a cursor */
2807
2800
MYDB_BEGIN_ALLOW_THREADS ;
2808
2801
err = self -> db -> cursor (self -> db , txn , & cursor , 0 );
2809
2802
MYDB_END_ALLOW_THREADS ;
2810
- RETURN_IF_ERR ();
2803
+ if (makeDBError (err )) {
2804
+ Py_DECREF (list );
2805
+ return NULL ;
2806
+ }
2811
2807
2812
2808
if (CHECK_DBFLAG (self , DB_THREAD )) {
2813
2809
key .flags = DB_DBT_REALLOC ;
@@ -2858,10 +2854,13 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
2858
2854
break ;
2859
2855
}
2860
2856
break ;
2857
+ default :
2858
+ PyErr_Format (PyExc_ValueError , "Unknown key type 0x%x" , type );
2859
+ item = NULL ;
2860
+ break ;
2861
2861
}
2862
2862
if (item == NULL ) {
2863
2863
Py_DECREF (list );
2864
- PyErr_SetString (PyExc_MemoryError , "List item creation failed" );
2865
2864
list = NULL ;
2866
2865
goto done ;
2867
2866
}
@@ -3199,6 +3198,7 @@ DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3199
3198
#else
3200
3199
retval = Py_BuildValue ("OOO" , keyObj , pkeyObj , dataObj );
3201
3200
#endif
3201
+ Py_DECREF (keyObj );
3202
3202
FREE_DBT (key );
3203
3203
}
3204
3204
else /* return just the pkey and data */
@@ -3209,6 +3209,8 @@ DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3209
3209
retval = Py_BuildValue ("OO" , pkeyObj , dataObj );
3210
3210
#endif
3211
3211
}
3212
+ Py_DECREF (dataObj );
3213
+ Py_DECREF (pkeyObj );
3212
3214
FREE_DBT (pkey );
3213
3215
FREE_DBT (data );
3214
3216
}
@@ -4384,18 +4386,14 @@ DBEnv_log_archive(DBEnvObject* self, PyObject* args)
4384
4386
RETURN_IF_ERR ();
4385
4387
4386
4388
list = PyList_New (0 );
4387
- if (list == NULL ) {
4388
- PyErr_SetString (PyExc_MemoryError , "PyList_New failed" );
4389
+ if (list == NULL )
4389
4390
return NULL ;
4390
- }
4391
4391
4392
4392
if (log_list ) {
4393
4393
for (log_list_start = log_list ; * log_list != NULL ; ++ log_list ) {
4394
4394
item = PyString_FromString (* log_list );
4395
4395
if (item == NULL ) {
4396
4396
Py_DECREF (list );
4397
- PyErr_SetString (PyExc_MemoryError ,
4398
- "List item creation failed" );
4399
4397
list = NULL ;
4400
4398
break ;
4401
4399
}
@@ -4492,8 +4490,10 @@ DBTxn_commit(DBTxnObject* self, PyObject* args)
4492
4490
return NULL ;
4493
4491
4494
4492
if (!self -> txn ) {
4495
- PyErr_SetObject (DBError , Py_BuildValue ("(is)" , 0 ,
4496
- "DBTxn must not be used after txn_commit or txn_abort" ));
4493
+ PyObject * t = Py_BuildValue ("(is)" , 0 , "DBTxn must not be used "
4494
+ "after txn_commit or txn_abort" );
4495
+ PyErr_SetObject (DBError , t );
4496
+ Py_DECREF (t );
4497
4497
return NULL ;
4498
4498
}
4499
4499
txn = self -> txn ;
@@ -4527,8 +4527,10 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
4527
4527
}
4528
4528
4529
4529
if (!self -> txn ) {
4530
- PyErr_SetObject (DBError , Py_BuildValue ("(is)" , 0 ,
4531
- "DBTxn must not be used after txn_commit or txn_abort" ));
4530
+ PyObject * t = Py_BuildValue ("(is)" , 0 ,"DBTxn must not be used "
4531
+ "after txn_commit or txn_abort" );
4532
+ PyErr_SetObject (DBError , t );
4533
+ Py_DECREF (t );
4532
4534
return NULL ;
4533
4535
}
4534
4536
MYDB_BEGIN_ALLOW_THREADS ;
@@ -4547,8 +4549,10 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
4547
4549
return NULL ;
4548
4550
4549
4551
if (!self -> txn ) {
4550
- PyErr_SetObject (DBError , Py_BuildValue ("(is)" , 0 ,
4551
- "DBTxn must not be used after txn_commit or txn_abort" ));
4552
+ PyObject * t = Py_BuildValue ("(is)" , 0 , "DBTxn must not be used "
4553
+ "after txn_commit or txn_abort" );
4554
+ PyErr_SetObject (DBError , t );
4555
+ Py_DECREF (t );
4552
4556
return NULL ;
4553
4557
}
4554
4558
MYDB_BEGIN_ALLOW_THREADS ;
@@ -4570,8 +4574,10 @@ DBTxn_abort(DBTxnObject* self, PyObject* args)
4570
4574
return NULL ;
4571
4575
4572
4576
if (!self -> txn ) {
4573
- PyErr_SetObject (DBError , Py_BuildValue ("(is)" , 0 ,
4574
- "DBTxn must not be used after txn_commit or txn_abort" ));
4577
+ PyObject * t = Py_BuildValue ("(is)" , 0 , "DBTxn must not be used "
4578
+ "after txn_commit or txn_abort" );
4579
+ PyErr_SetObject (DBError , t );
4580
+ Py_DECREF (t );
4575
4581
return NULL ;
4576
4582
}
4577
4583
txn = self -> txn ;
@@ -4597,8 +4603,10 @@ DBTxn_id(DBTxnObject* self, PyObject* args)
4597
4603
return NULL ;
4598
4604
4599
4605
if (!self -> txn ) {
4600
- PyErr_SetObject (DBError , Py_BuildValue ("(is)" , 0 ,
4601
- "DBTxn must not be used after txn_commit or txn_abort" ));
4606
+ PyObject * t = Py_BuildValue ("(is)" , 0 , "DBTxn must not be used "
4607
+ "after txn_commit or txn_abort" );
4608
+ PyErr_SetObject (DBError , t );
4609
+ Py_DECREF (t );
4602
4610
return NULL ;
4603
4611
}
4604
4612
MYDB_BEGIN_ALLOW_THREADS ;
0 commit comments