[3.4] [3.5] bpo-27945: Fixed various segfaults with dict. (GH-1657) (… · python/cpython@f734479 (original) (raw)
`@@ -805,56 +805,61 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
805
805
`PyDictKeyEntry *ep;
`
806
806
`assert(key != dummy);
`
807
807
``
``
808
`+
Py_INCREF(key);
`
``
809
`+
Py_INCREF(value);
`
808
810
`if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
`
809
811
`if (insertion_resize(mp) < 0)
`
810
``
`-
return -1;
`
``
812
`+
goto Fail;
`
811
813
` }
`
812
814
``
813
815
`ep = mp->ma_keys->dk_lookup(mp, key, hash, &value_addr);
`
814
``
`-
if (ep == NULL) {
`
815
``
`-
return -1;
`
816
``
`-
}
`
``
816
`+
if (ep == NULL)
`
``
817
`+
goto Fail;
`
``
818
+
817
819
`assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
`
818
``
`-
Py_INCREF(value);
`
819
820
`MAINTAIN_TRACKING(mp, key, value);
`
820
821
`old_value = *value_addr;
`
821
822
`if (old_value != NULL) {
`
822
823
`assert(ep->me_key != NULL && ep->me_key != dummy);
`
823
824
`*value_addr = value;
`
824
825
`Py_DECREF(old_value); /* which CAN re-enter (see issue #22653) */
`
``
826
`+
Py_DECREF(key);
`
825
827
` }
`
826
828
`else {
`
827
829
`if (ep->me_key == NULL) {
`
828
``
`-
Py_INCREF(key);
`
829
830
`if (mp->ma_keys->dk_usable <= 0) {
`
830
831
`/* Need to resize. */
`
831
``
`-
if (insertion_resize(mp) < 0) {
`
832
``
`-
Py_DECREF(key);
`
833
``
`-
Py_DECREF(value);
`
834
``
`-
return -1;
`
835
``
`-
}
`
``
832
`+
if (insertion_resize(mp) < 0)
`
``
833
`+
goto Fail;
`
836
834
`ep = find_empty_slot(mp, key, hash, &value_addr);
`
837
835
` }
`
``
836
`+
mp->ma_used++;
`
``
837
`+
*value_addr = value;
`
838
838
`mp->ma_keys->dk_usable--;
`
839
839
`assert(mp->ma_keys->dk_usable >= 0);
`
840
840
`ep->me_key = key;
`
841
841
`ep->me_hash = hash;
`
``
842
`+
assert(ep->me_key != NULL && ep->me_key != dummy);
`
842
843
` }
`
843
844
`else {
`
``
845
`+
mp->ma_used++;
`
``
846
`+
*value_addr = value;
`
844
847
`if (ep->me_key == dummy) {
`
845
``
`-
Py_INCREF(key);
`
846
848
`ep->me_key = key;
`
847
849
`ep->me_hash = hash;
`
848
850
`Py_DECREF(dummy);
`
849
851
` } else {
`
850
852
`assert(_PyDict_HasSplitTable(mp));
`
``
853
`+
Py_DECREF(key);
`
851
854
` }
`
852
855
` }
`
853
``
`-
mp->ma_used++;
`
854
``
`-
*value_addr = value;
`
855
``
`-
assert(ep->me_key != NULL && ep->me_key != dummy);
`
856
856
` }
`
857
857
`return 0;
`
``
858
+
``
859
`+
Fail:
`
``
860
`+
Py_DECREF(value);
`
``
861
`+
Py_DECREF(key);
`
``
862
`+
return -1;
`
858
863
`}
`
859
864
``
860
865
`/*
`
`@@ -1911,11 +1916,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
`
1911
1916
`/* Update/merge with this (key, value) pair. */
`
1912
1917
`key = PySequence_Fast_GET_ITEM(fast, 0);
`
1913
1918
`value = PySequence_Fast_GET_ITEM(fast, 1);
`
``
1919
`+
Py_INCREF(key);
`
``
1920
`+
Py_INCREF(value);
`
1914
1921
`if (override || PyDict_GetItem(d, key) == NULL) {
`
1915
1922
`int status = PyDict_SetItem(d, key, value);
`
1916
``
`-
if (status < 0)
`
``
1923
`+
if (status < 0) {
`
``
1924
`+
Py_DECREF(key);
`
``
1925
`+
Py_DECREF(value);
`
1917
1926
` goto Fail;
`
``
1927
`+
}
`
1918
1928
` }
`
``
1929
`+
Py_DECREF(key);
`
``
1930
`+
Py_DECREF(value);
`
1919
1931
`Py_DECREF(fast);
`
1920
1932
`Py_DECREF(item);
`
1921
1933
` }
`
`@@ -2174,14 +2186,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)
`
2174
2186
`bval = NULL;
`
2175
2187
`else
`
2176
2188
`bval = *vaddr;
`
2177
``
`-
Py_DECREF(key);
`
2178
2189
`if (bval == NULL) {
`
``
2190
`+
Py_DECREF(key);
`
2179
2191
`Py_DECREF(aval);
`
2180
2192
`if (PyErr_Occurred())
`
2181
2193
`return -1;
`
2182
2194
`return 0;
`
2183
2195
` }
`
2184
2196
`cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
`
``
2197
`+
Py_DECREF(key);
`
2185
2198
`Py_DECREF(aval);
`
2186
2199
`if (cmp <= 0) /* error or not equal */
`
2187
2200
`return cmp;
`
`@@ -3046,7 +3059,7 @@ PyTypeObject PyDictIterValue_Type = {
`
3046
3059
``
3047
3060
`static PyObject *dictiter_iternextitem(dictiterobject *di)
`
3048
3061
`{
`
3049
``
`-
PyObject *key, *value, *result = di->di_result;
`
``
3062
`+
PyObject *key, *value, *result;
`
3050
3063
`Py_ssize_t i, mask, offset;
`
3051
3064
`PyDictObject *d = di->di_dict;
`
3052
3065
`PyObject **value_ptr;
`
`@@ -3082,22 +3095,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)
`
3082
3095
`if (i > mask)
`
3083
3096
` goto fail;
`
3084
3097
``
3085
``
`-
if (result->ob_refcnt == 1) {
`
``
3098
`+
di->len--;
`
``
3099
`+
key = d->ma_keys->dk_entries[i].me_key;
`
``
3100
`+
value = *value_ptr;
`
``
3101
`+
Py_INCREF(key);
`
``
3102
`+
Py_INCREF(value);
`
``
3103
`+
result = di->di_result;
`
``
3104
`+
if (Py_REFCNT(result) == 1) {
`
``
3105
`+
PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
`
``
3106
`+
PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
`
``
3107
`+
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
``
3108
`+
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3086
3109
`Py_INCREF(result);
`
3087
``
`-
Py_DECREF(PyTuple_GET_ITEM(result, 0));
`
3088
``
`-
Py_DECREF(PyTuple_GET_ITEM(result, 1));
`
``
3110
`+
Py_DECREF(oldkey);
`
``
3111
`+
Py_DECREF(oldvalue);
`
3089
3112
` } else {
`
3090
3113
`result = PyTuple_New(2);
`
3091
3114
`if (result == NULL)
`
3092
3115
`return NULL;
`
``
3116
`+
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
``
3117
`+
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3093
3118
` }
`
3094
``
`-
di->len--;
`
3095
``
`-
key = d->ma_keys->dk_entries[i].me_key;
`
3096
``
`-
value = *value_ptr;
`
3097
``
`-
Py_INCREF(key);
`
3098
``
`-
Py_INCREF(value);
`
3099
``
`-
PyTuple_SET_ITEM(result, 0, key);
`
3100
``
`-
PyTuple_SET_ITEM(result, 1, value);
`
3101
3119
`return result;
`
3102
3120
``
3103
3121
`fail:
`
`@@ -3596,6 +3614,7 @@ dictitems_iter(dictviewobject *dv)
`
3596
3614
`static int
`
3597
3615
`dictitems_contains(dictviewobject *dv, PyObject *obj)
`
3598
3616
`{
`
``
3617
`+
int result;
`
3599
3618
`PyObject *key, *value, *found;
`
3600
3619
`if (dv->dv_dict == NULL)
`
3601
3620
`return 0;
`
`@@ -3609,7 +3628,10 @@ dictitems_contains(dictviewobject *dv, PyObject *obj)
`
3609
3628
`return -1;
`
3610
3629
`return 0;
`
3611
3630
` }
`
3612
``
`-
return PyObject_RichCompareBool(value, found, Py_EQ);
`
``
3631
`+
Py_INCREF(found);
`
``
3632
`+
result = PyObject_RichCompareBool(value, found, Py_EQ);
`
``
3633
`+
Py_DECREF(found);
`
``
3634
`+
return result;
`
3613
3635
`}
`
3614
3636
``
3615
3637
`static PySequenceMethods dictitems_as_sequence = {
`