@@ -810,56 +810,62 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
810810 PyDictKeyEntry * ep ;
811811 assert (key != dummy );
812812
813+ Py_INCREF (key );
814+ Py_INCREF (value );
813815 if (mp -> ma_values != NULL && !PyUnicode_CheckExact (key )) {
814816 if (insertion_resize (mp ) < 0 )
815- return -1 ;
817+ goto Fail ;
816818 }
817819
818820 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+
823824 MAINTAIN_TRACKING (mp , key , value );
824825 old_value = * value_addr ;
825826 if (old_value != NULL ) {
826827 assert (ep -> me_key != NULL && ep -> me_key != dummy );
827828 * 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 );
829831 }
830832 else {
831833 if (ep -> me_key == NULL ) {
832- Py_INCREF (key );
833834 if (mp -> ma_keys -> dk_usable <= 0 ) {
834835 /* 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 ;
840838 ep = find_empty_slot (mp , key , hash , & value_addr );
841839 }
840+ mp -> ma_used ++ ;
841+ * value_addr = value ;
842842 mp -> ma_keys -> dk_usable -- ;
843843 assert (mp -> ma_keys -> dk_usable >= 0 );
844844 ep -> me_key = key ;
845845 ep -> me_hash = hash ;
846+ assert (ep -> me_key != NULL && ep -> me_key != dummy );
846847 }
847848 else {
849+ mp -> ma_used ++ ;
850+ * value_addr = value ;
848851 if (ep -> me_key == dummy ) {
849- Py_INCREF (key );
850852 ep -> me_key = key ;
851853 ep -> me_hash = hash ;
852854 Py_DECREF (dummy );
853855 } else {
854856 assert (_PyDict_HasSplitTable (mp ));
857+ Py_DECREF (key );
855858 }
856859 }
857- mp -> ma_used ++ ;
858- * value_addr = value ;
859860 }
860861 assert (ep -> me_key != NULL && ep -> me_key != dummy );
861862 assert (PyUnicode_CheckExact (key ) || mp -> ma_keys -> dk_lookup == lookdict );
862863 return 0 ;
864+
865+ Fail :
866+ Py_DECREF (value );
867+ Py_DECREF (key );
868+ return -1 ;
863869}
864870
865871/*
@@ -1879,11 +1885,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
18791885 /* Update/merge with this (key, value) pair. */
18801886 key = PySequence_Fast_GET_ITEM (fast , 0 );
18811887 value = PySequence_Fast_GET_ITEM (fast , 1 );
1888+ Py_INCREF (key );
1889+ Py_INCREF (value );
18821890 if (override || PyDict_GetItem (d , key ) == NULL ) {
18831891 int status = PyDict_SetItem (d , key , value );
1884- if (status < 0 )
1892+ if (status < 0 ) {
1893+ Py_DECREF (key );
1894+ Py_DECREF (value );
18851895 goto Fail ;
1896+ }
18861897 }
1898+ Py_DECREF (key );
1899+ Py_DECREF (value );
18871900 Py_DECREF (fast );
18881901 Py_DECREF (item );
18891902 }
@@ -2137,14 +2150,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)
21372150 /* ditto for key */
21382151 Py_INCREF (key );
21392152 bval = PyDict_GetItemWithError ((PyObject * )b , key );
2140- Py_DECREF (key );
21412153 if (bval == NULL ) {
2154+ Py_DECREF (key );
21422155 Py_DECREF (aval );
21432156 if (PyErr_Occurred ())
21442157 return -1 ;
21452158 return 0 ;
21462159 }
21472160 cmp = PyObject_RichCompareBool (aval , bval , Py_EQ );
2161+ Py_DECREF (key );
21482162 Py_DECREF (aval );
21492163 if (cmp <= 0 ) /* error or not equal */
21502164 return cmp ;
@@ -2970,7 +2984,7 @@ PyTypeObject PyDictIterValue_Type = {
29702984
29712985static PyObject * dictiter_iternextitem (dictiterobject * di )
29722986{
2973- PyObject * key , * value , * result = di -> di_result ;
2987+ PyObject * key , * value , * result ;
29742988 register Py_ssize_t i , mask , offset ;
29752989 PyDictObject * d = di -> di_dict ;
29762990 PyObject * * value_ptr ;
@@ -3006,22 +3020,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)
30063020 if (i > mask )
30073021 goto fail ;
30083022
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 */
30103034 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 );
30133037 } else {
30143038 result = PyTuple_New (2 );
30153039 if (result == NULL )
30163040 return NULL ;
3041+ PyTuple_SET_ITEM (result , 0 , key ); /* steals reference */
3042+ PyTuple_SET_ITEM (result , 1 , value ); /* steals reference */
30173043 }
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 );
30253044 return result ;
30263045
30273046fail :
@@ -3521,6 +3540,7 @@ dictitems_iter(dictviewobject *dv)
35213540static int
35223541dictitems_contains (dictviewobject * dv , PyObject * obj )
35233542{
3543+ int result ;
35243544 PyObject * key , * value , * found ;
35253545 if (dv -> dv_dict == NULL )
35263546 return 0 ;
@@ -3534,7 +3554,10 @@ dictitems_contains(dictviewobject *dv, PyObject *obj)
35343554 return -1 ;
35353555 return 0 ;
35363556 }
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 ;
35383561}
35393562
35403563static PySequenceMethods dictitems_as_sequence = {
0 commit comments