@@ -787,56 +787,61 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
787
787
PyDictKeyEntry * ep ;
788
788
assert (key != dummy );
789
789
790
+ Py_INCREF (key );
791
+ Py_INCREF (value );
790
792
if (mp -> ma_values != NULL && !PyUnicode_CheckExact (key )) {
791
793
if (insertion_resize (mp ) < 0 )
792
- return -1 ;
794
+ goto Fail ;
793
795
}
794
796
795
797
ep = mp -> ma_keys -> dk_lookup (mp , key , hash , & value_addr );
796
- if (ep == NULL ) {
797
- return -1 ;
798
- }
798
+ if (ep == NULL )
799
+ goto Fail ;
800
+
799
801
assert (PyUnicode_CheckExact (key ) || mp -> ma_keys -> dk_lookup == lookdict );
800
- Py_INCREF (value );
801
802
MAINTAIN_TRACKING (mp , key , value );
802
803
old_value = * value_addr ;
803
804
if (old_value != NULL ) {
804
805
assert (ep -> me_key != NULL && ep -> me_key != dummy );
805
806
* value_addr = value ;
806
807
Py_DECREF (old_value ); /* which **CAN** re-enter (see issue #22653) */
808
+ Py_DECREF (key );
807
809
}
808
810
else {
809
811
if (ep -> me_key == NULL ) {
810
- Py_INCREF (key );
811
812
if (mp -> ma_keys -> dk_usable <= 0 ) {
812
813
/* Need to resize. */
813
- if (insertion_resize (mp ) < 0 ) {
814
- Py_DECREF (key );
815
- Py_DECREF (value );
816
- return -1 ;
817
- }
814
+ if (insertion_resize (mp ) < 0 )
815
+ goto Fail ;
818
816
ep = find_empty_slot (mp , key , hash , & value_addr );
819
817
}
818
+ mp -> ma_used ++ ;
819
+ * value_addr = value ;
820
820
mp -> ma_keys -> dk_usable -- ;
821
821
assert (mp -> ma_keys -> dk_usable >= 0 );
822
822
ep -> me_key = key ;
823
823
ep -> me_hash = hash ;
824
+ assert (ep -> me_key != NULL && ep -> me_key != dummy );
824
825
}
825
826
else {
827
+ mp -> ma_used ++ ;
828
+ * value_addr = value ;
826
829
if (ep -> me_key == dummy ) {
827
- Py_INCREF (key );
828
830
ep -> me_key = key ;
829
831
ep -> me_hash = hash ;
830
832
Py_DECREF (dummy );
831
833
} else {
832
834
assert (_PyDict_HasSplitTable (mp ));
835
+ Py_DECREF (key );
833
836
}
834
837
}
835
- mp -> ma_used ++ ;
836
- * value_addr = value ;
837
- assert (ep -> me_key != NULL && ep -> me_key != dummy );
838
838
}
839
839
return 0 ;
840
+
841
+ Fail :
842
+ Py_DECREF (value );
843
+ Py_DECREF (key );
844
+ return -1 ;
840
845
}
841
846
842
847
/*
@@ -2057,11 +2062,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
2057
2062
/* Update/merge with this (key, value) pair. */
2058
2063
key = PySequence_Fast_GET_ITEM (fast , 0 );
2059
2064
value = PySequence_Fast_GET_ITEM (fast , 1 );
2065
+ Py_INCREF (key );
2066
+ Py_INCREF (value );
2060
2067
if (override || PyDict_GetItem (d , key ) == NULL ) {
2061
2068
int status = PyDict_SetItem (d , key , value );
2062
- if (status < 0 )
2069
+ if (status < 0 ) {
2070
+ Py_DECREF (key );
2071
+ Py_DECREF (value );
2063
2072
goto Fail ;
2073
+ }
2064
2074
}
2075
+ Py_DECREF (key );
2076
+ Py_DECREF (value );
2065
2077
Py_DECREF (fast );
2066
2078
Py_DECREF (item );
2067
2079
}
@@ -2320,14 +2332,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)
2320
2332
bval = NULL ;
2321
2333
else
2322
2334
bval = * vaddr ;
2323
- Py_DECREF (key );
2324
2335
if (bval == NULL ) {
2336
+ Py_DECREF (key );
2325
2337
Py_DECREF (aval );
2326
2338
if (PyErr_Occurred ())
2327
2339
return -1 ;
2328
2340
return 0 ;
2329
2341
}
2330
2342
cmp = PyObject_RichCompareBool (aval , bval , Py_EQ );
2343
+ Py_DECREF (key );
2331
2344
Py_DECREF (aval );
2332
2345
if (cmp <= 0 ) /* error or not equal */
2333
2346
return cmp ;
@@ -3152,7 +3165,7 @@ PyTypeObject PyDictIterValue_Type = {
3152
3165
3153
3166
static PyObject * dictiter_iternextitem (dictiterobject * di )
3154
3167
{
3155
- PyObject * key , * value , * result = di -> di_result ;
3168
+ PyObject * key , * value , * result ;
3156
3169
Py_ssize_t i , mask , offset ;
3157
3170
PyDictObject * d = di -> di_dict ;
3158
3171
PyObject * * value_ptr ;
@@ -3188,22 +3201,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)
3188
3201
if (i > mask )
3189
3202
goto fail ;
3190
3203
3191
- if (result -> ob_refcnt == 1 ) {
3204
+ di -> len -- ;
3205
+ key = d -> ma_keys -> dk_entries [i ].me_key ;
3206
+ value = * value_ptr ;
3207
+ Py_INCREF (key );
3208
+ Py_INCREF (value );
3209
+ result = di -> di_result ;
3210
+ if (Py_REFCNT (result ) == 1 ) {
3211
+ PyObject * oldkey = PyTuple_GET_ITEM (result , 0 );
3212
+ PyObject * oldvalue = PyTuple_GET_ITEM (result , 1 );
3213
+ PyTuple_SET_ITEM (result , 0 , key ); /* steals reference */
3214
+ PyTuple_SET_ITEM (result , 1 , value ); /* steals reference */
3192
3215
Py_INCREF (result );
3193
- Py_DECREF (PyTuple_GET_ITEM ( result , 0 ) );
3194
- Py_DECREF (PyTuple_GET_ITEM ( result , 1 ) );
3216
+ Py_DECREF (oldkey );
3217
+ Py_DECREF (oldvalue );
3195
3218
} else {
3196
3219
result = PyTuple_New (2 );
3197
3220
if (result == NULL )
3198
3221
return NULL ;
3222
+ PyTuple_SET_ITEM (result , 0 , key ); /* steals reference */
3223
+ PyTuple_SET_ITEM (result , 1 , value ); /* steals reference */
3199
3224
}
3200
- di -> len -- ;
3201
- key = d -> ma_keys -> dk_entries [i ].me_key ;
3202
- value = * value_ptr ;
3203
- Py_INCREF (key );
3204
- Py_INCREF (value );
3205
- PyTuple_SET_ITEM (result , 0 , key ); /* steals reference */
3206
- PyTuple_SET_ITEM (result , 1 , value ); /* steals reference */
3207
3225
return result ;
3208
3226
3209
3227
fail :
@@ -3696,6 +3714,7 @@ dictitems_iter(_PyDictViewObject *dv)
3696
3714
static int
3697
3715
dictitems_contains (_PyDictViewObject * dv , PyObject * obj )
3698
3716
{
3717
+ int result ;
3699
3718
PyObject * key , * value , * found ;
3700
3719
if (dv -> dv_dict == NULL )
3701
3720
return 0 ;
@@ -3709,7 +3728,10 @@ dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
3709
3728
return -1 ;
3710
3729
return 0 ;
3711
3730
}
3712
- return PyObject_RichCompareBool (value , found , Py_EQ );
3731
+ Py_INCREF (found );
3732
+ result = PyObject_RichCompareBool (value , found , Py_EQ );
3733
+ Py_DECREF (found );
3734
+ return result ;
3713
3735
}
3714
3736
3715
3737
static PySequenceMethods dictitems_as_sequence = {
0 commit comments