@@ -810,56 +810,62 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
810
810
PyDictKeyEntry * ep ;
811
811
assert (key != dummy );
812
812
813
+ Py_INCREF (key );
814
+ Py_INCREF (value );
813
815
if (mp -> ma_values != NULL && !PyUnicode_CheckExact (key )) {
814
816
if (insertion_resize (mp ) < 0 )
815
- return -1 ;
817
+ goto Fail ;
816
818
}
817
819
818
820
ep = mp -> ma_keys -> dk_lookup (mp , key , hash , & value_addr );
819
- if (ep == NULL ) {
820
- return -1 ;
821
- }
822
- Py_INCREF (value );
821
+ if (ep == NULL )
822
+ goto Fail ;
823
+
823
824
MAINTAIN_TRACKING (mp , key , value );
824
825
old_value = * value_addr ;
825
826
if (old_value != NULL ) {
826
827
assert (ep -> me_key != NULL && ep -> me_key != dummy );
827
828
* value_addr = value ;
828
- Py_DECREF (old_value ); /* which **CAN** re-enter */
829
+ Py_DECREF (old_value ); /* which **CAN** re-enter (see issue #22653) */
830
+ Py_DECREF (key );
829
831
}
830
832
else {
831
833
if (ep -> me_key == NULL ) {
832
- Py_INCREF (key );
833
834
if (mp -> ma_keys -> dk_usable <= 0 ) {
834
835
/* Need to resize. */
835
- if (insertion_resize (mp ) < 0 ) {
836
- Py_DECREF (key );
837
- Py_DECREF (value );
838
- return -1 ;
839
- }
836
+ if (insertion_resize (mp ) < 0 )
837
+ goto Fail ;
840
838
ep = find_empty_slot (mp , key , hash , & value_addr );
841
839
}
840
+ mp -> ma_used ++ ;
841
+ * value_addr = value ;
842
842
mp -> ma_keys -> dk_usable -- ;
843
843
assert (mp -> ma_keys -> dk_usable >= 0 );
844
844
ep -> me_key = key ;
845
845
ep -> me_hash = hash ;
846
+ assert (ep -> me_key != NULL && ep -> me_key != dummy );
846
847
}
847
848
else {
849
+ mp -> ma_used ++ ;
850
+ * value_addr = value ;
848
851
if (ep -> me_key == dummy ) {
849
- Py_INCREF (key );
850
852
ep -> me_key = key ;
851
853
ep -> me_hash = hash ;
852
854
Py_DECREF (dummy );
853
855
} else {
854
856
assert (_PyDict_HasSplitTable (mp ));
857
+ Py_DECREF (key );
855
858
}
856
859
}
857
- mp -> ma_used ++ ;
858
- * value_addr = value ;
859
860
}
860
861
assert (ep -> me_key != NULL && ep -> me_key != dummy );
861
862
assert (PyUnicode_CheckExact (key ) || mp -> ma_keys -> dk_lookup == lookdict );
862
863
return 0 ;
864
+
865
+ Fail :
866
+ Py_DECREF (value );
867
+ Py_DECREF (key );
868
+ return -1 ;
863
869
}
864
870
865
871
/*
@@ -1879,11 +1885,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
1879
1885
/* Update/merge with this (key, value) pair. */
1880
1886
key = PySequence_Fast_GET_ITEM (fast , 0 );
1881
1887
value = PySequence_Fast_GET_ITEM (fast , 1 );
1888
+ Py_INCREF (key );
1889
+ Py_INCREF (value );
1882
1890
if (override || PyDict_GetItem (d , key ) == NULL ) {
1883
1891
int status = PyDict_SetItem (d , key , value );
1884
- if (status < 0 )
1892
+ if (status < 0 ) {
1893
+ Py_DECREF (key );
1894
+ Py_DECREF (value );
1885
1895
goto Fail ;
1896
+ }
1886
1897
}
1898
+ Py_DECREF (key );
1899
+ Py_DECREF (value );
1887
1900
Py_DECREF (fast );
1888
1901
Py_DECREF (item );
1889
1902
}
@@ -2137,14 +2150,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)
2137
2150
/* ditto for key */
2138
2151
Py_INCREF (key );
2139
2152
bval = PyDict_GetItemWithError ((PyObject * )b , key );
2140
- Py_DECREF (key );
2141
2153
if (bval == NULL ) {
2154
+ Py_DECREF (key );
2142
2155
Py_DECREF (aval );
2143
2156
if (PyErr_Occurred ())
2144
2157
return -1 ;
2145
2158
return 0 ;
2146
2159
}
2147
2160
cmp = PyObject_RichCompareBool (aval , bval , Py_EQ );
2161
+ Py_DECREF (key );
2148
2162
Py_DECREF (aval );
2149
2163
if (cmp <= 0 ) /* error or not equal */
2150
2164
return cmp ;
@@ -2970,7 +2984,7 @@ PyTypeObject PyDictIterValue_Type = {
2970
2984
2971
2985
static PyObject * dictiter_iternextitem (dictiterobject * di )
2972
2986
{
2973
- PyObject * key , * value , * result = di -> di_result ;
2987
+ PyObject * key , * value , * result ;
2974
2988
register Py_ssize_t i , mask , offset ;
2975
2989
PyDictObject * d = di -> di_dict ;
2976
2990
PyObject * * value_ptr ;
@@ -3006,22 +3020,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)
3006
3020
if (i > mask )
3007
3021
goto fail ;
3008
3022
3009
- if (result -> ob_refcnt == 1 ) {
3023
+ di -> len -- ;
3024
+ key = d -> ma_keys -> dk_entries [i ].me_key ;
3025
+ value = * value_ptr ;
3026
+ Py_INCREF (key );
3027
+ Py_INCREF (value );
3028
+ result = di -> di_result ;
3029
+ if (Py_REFCNT (result ) == 1 ) {
3030
+ PyObject * oldkey = PyTuple_GET_ITEM (result , 0 );
3031
+ PyObject * oldvalue = PyTuple_GET_ITEM (result , 1 );
3032
+ PyTuple_SET_ITEM (result , 0 , key ); /* steals reference */
3033
+ PyTuple_SET_ITEM (result , 1 , value ); /* steals reference */
3010
3034
Py_INCREF (result );
3011
- Py_DECREF (PyTuple_GET_ITEM ( result , 0 ) );
3012
- Py_DECREF (PyTuple_GET_ITEM ( result , 1 ) );
3035
+ Py_DECREF (oldkey );
3036
+ Py_DECREF (oldvalue );
3013
3037
} else {
3014
3038
result = PyTuple_New (2 );
3015
3039
if (result == NULL )
3016
3040
return NULL ;
3041
+ PyTuple_SET_ITEM (result , 0 , key ); /* steals reference */
3042
+ PyTuple_SET_ITEM (result , 1 , value ); /* steals reference */
3017
3043
}
3018
- di -> len -- ;
3019
- key = d -> ma_keys -> dk_entries [i ].me_key ;
3020
- value = * value_ptr ;
3021
- Py_INCREF (key );
3022
- Py_INCREF (value );
3023
- PyTuple_SET_ITEM (result , 0 , key );
3024
- PyTuple_SET_ITEM (result , 1 , value );
3025
3044
return result ;
3026
3045
3027
3046
fail :
@@ -3521,6 +3540,7 @@ dictitems_iter(dictviewobject *dv)
3521
3540
static int
3522
3541
dictitems_contains (dictviewobject * dv , PyObject * obj )
3523
3542
{
3543
+ int result ;
3524
3544
PyObject * key , * value , * found ;
3525
3545
if (dv -> dv_dict == NULL )
3526
3546
return 0 ;
@@ -3534,7 +3554,10 @@ dictitems_contains(dictviewobject *dv, PyObject *obj)
3534
3554
return -1 ;
3535
3555
return 0 ;
3536
3556
}
3537
- return PyObject_RichCompareBool (value , found , Py_EQ );
3557
+ Py_INCREF (found );
3558
+ result = PyObject_RichCompareBool (value , found , Py_EQ );
3559
+ Py_DECREF (found );
3560
+ return result ;
3538
3561
}
3539
3562
3540
3563
static PySequenceMethods dictitems_as_sequence = {
0 commit comments