[3.5] bpo-27945: Fixed various segfaults with dict. (GH-1657) (#1678) · python/cpython@2f7f533 (original) (raw)
`@@ -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 = {
`