[3.6] bpo-27945: Fixed various segfaults with dict. (GH-1657) (#1677) · python/cpython@564398a (original) (raw)
`@@ -1115,18 +1115,18 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1115
1115
`PyDictKeyEntry *ep, *ep0;
`
1116
1116
`Py_ssize_t hashpos, ix;
`
1117
1117
``
``
1118
`+
Py_INCREF(key);
`
``
1119
`+
Py_INCREF(value);
`
1118
1120
`if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
`
1119
1121
`if (insertion_resize(mp) < 0)
`
1120
``
`-
return -1;
`
``
1122
`+
goto Fail;
`
1121
1123
` }
`
1122
1124
``
1123
1125
`ix = mp->ma_keys->dk_lookup(mp, key, hash, &value_addr, &hashpos);
`
1124
``
`-
if (ix == DKIX_ERROR) {
`
1125
``
`-
return -1;
`
1126
``
`-
}
`
``
1126
`+
if (ix == DKIX_ERROR)
`
``
1127
`+
goto Fail;
`
1127
1128
``
1128
1129
`assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
`
1129
``
`-
Py_INCREF(value);
`
1130
1130
`MAINTAIN_TRACKING(mp, key, value);
`
1131
1131
``
1132
1132
`/* When insertion order is different from shared key, we can't share
`
`@@ -1135,10 +1135,8 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1135
1135
`if (_PyDict_HasSplitTable(mp) &&
`
1136
1136
` ((ix >= 0 && *value_addr == NULL && mp->ma_used != ix) ||
`
1137
1137
` (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
`
1138
``
`-
if (insertion_resize(mp) < 0) {
`
1139
``
`-
Py_DECREF(value);
`
1140
``
`-
return -1;
`
1141
``
`-
}
`
``
1138
`+
if (insertion_resize(mp) < 0)
`
``
1139
`+
goto Fail;
`
1142
1140
`find_empty_slot(mp, key, hash, &value_addr, &hashpos);
`
1143
1141
`ix = DKIX_EMPTY;
`
1144
1142
` }
`
`@@ -1147,16 +1145,13 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1147
1145
`/* Insert into new slot. */
`
1148
1146
`if (mp->ma_keys->dk_usable <= 0) {
`
1149
1147
`/* Need to resize. */
`
1150
``
`-
if (insertion_resize(mp) < 0) {
`
1151
``
`-
Py_DECREF(value);
`
1152
``
`-
return -1;
`
1153
``
`-
}
`
``
1148
`+
if (insertion_resize(mp) < 0)
`
``
1149
`+
goto Fail;
`
1154
1150
`find_empty_slot(mp, key, hash, &value_addr, &hashpos);
`
1155
1151
` }
`
1156
1152
`ep0 = DK_ENTRIES(mp->ma_keys);
`
1157
1153
`ep = &ep0[mp->ma_keys->dk_nentries];
`
1158
1154
`dk_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
`
1159
``
`-
Py_INCREF(key);
`
1160
1155
`ep->me_key = key;
`
1161
1156
`ep->me_hash = hash;
`
1162
1157
`if (mp->ma_values) {
`
`@@ -1184,6 +1179,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1184
1179
`assert(_PyDict_CheckConsistency(mp));
`
1185
1180
``
1186
1181
`Py_DECREF(old_value); /* which CAN re-enter (see issue #22653) */
`
``
1182
`+
Py_DECREF(key);
`
1187
1183
`return 0;
`
1188
1184
` }
`
1189
1185
``
`@@ -1194,7 +1190,13 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1194
1190
`mp->ma_used++;
`
1195
1191
`mp->ma_version_tag = DICT_NEXT_VERSION();
`
1196
1192
`assert(_PyDict_CheckConsistency(mp));
`
``
1193
`+
Py_DECREF(key);
`
1197
1194
`return 0;
`
``
1195
+
``
1196
`+
Fail:
`
``
1197
`+
Py_DECREF(value);
`
``
1198
`+
Py_DECREF(key);
`
``
1199
`+
return -1;
`
1198
1200
`}
`
1199
1201
``
1200
1202
`/*
`
`@@ -2432,11 +2434,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
`
2432
2434
`/* Update/merge with this (key, value) pair. */
`
2433
2435
`key = PySequence_Fast_GET_ITEM(fast, 0);
`
2434
2436
`value = PySequence_Fast_GET_ITEM(fast, 1);
`
``
2437
`+
Py_INCREF(key);
`
``
2438
`+
Py_INCREF(value);
`
2435
2439
`if (override || PyDict_GetItem(d, key) == NULL) {
`
2436
2440
`int status = PyDict_SetItem(d, key, value);
`
2437
``
`-
if (status < 0)
`
``
2441
`+
if (status < 0) {
`
``
2442
`+
Py_DECREF(key);
`
``
2443
`+
Py_DECREF(value);
`
2438
2444
` goto Fail;
`
``
2445
`+
}
`
2439
2446
` }
`
``
2447
`+
Py_DECREF(key);
`
``
2448
`+
Py_DECREF(value);
`
2440
2449
`Py_DECREF(fast);
`
2441
2450
`Py_DECREF(item);
`
2442
2451
` }
`
`@@ -2737,14 +2746,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)
`
2737
2746
`bval = NULL;
`
2738
2747
`else
`
2739
2748
`bval = *vaddr;
`
2740
``
`-
Py_DECREF(key);
`
2741
2749
`if (bval == NULL) {
`
``
2750
`+
Py_DECREF(key);
`
2742
2751
`Py_DECREF(aval);
`
2743
2752
`if (PyErr_Occurred())
`
2744
2753
`return -1;
`
2745
2754
`return 0;
`
2746
2755
` }
`
2747
2756
`cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
`
``
2757
`+
Py_DECREF(key);
`
2748
2758
`Py_DECREF(aval);
`
2749
2759
`if (cmp <= 0) /* error or not equal */
`
2750
2760
`return cmp;
`
`@@ -3633,7 +3643,7 @@ PyTypeObject PyDictIterValue_Type = {
`
3633
3643
`static PyObject *
`
3634
3644
`dictiter_iternextitem(dictiterobject *di)
`
3635
3645
`{
`
3636
``
`-
PyObject *key, *value, *result = di->di_result;
`
``
3646
`+
PyObject *key, *value, *result;
`
3637
3647
`Py_ssize_t i, n;
`
3638
3648
`PyDictObject *d = di->di_dict;
`
3639
3649
``
`@@ -3674,20 +3684,25 @@ dictiter_iternextitem(dictiterobject *di)
`
3674
3684
` }
`
3675
3685
`di->di_pos = i+1;
`
3676
3686
`di->len--;
`
3677
``
`-
if (result->ob_refcnt == 1) {
`
``
3687
`+
Py_INCREF(key);
`
``
3688
`+
Py_INCREF(value);
`
``
3689
`+
result = di->di_result;
`
``
3690
`+
if (Py_REFCNT(result) == 1) {
`
``
3691
`+
PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
`
``
3692
`+
PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
`
``
3693
`+
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
``
3694
`+
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3678
3695
`Py_INCREF(result);
`
3679
``
`-
Py_DECREF(PyTuple_GET_ITEM(result, 0));
`
3680
``
`-
Py_DECREF(PyTuple_GET_ITEM(result, 1));
`
``
3696
`+
Py_DECREF(oldkey);
`
``
3697
`+
Py_DECREF(oldvalue);
`
3681
3698
` }
`
3682
3699
`else {
`
3683
3700
`result = PyTuple_New(2);
`
3684
3701
`if (result == NULL)
`
3685
3702
`return NULL;
`
``
3703
`+
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
``
3704
`+
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3686
3705
` }
`
3687
``
`-
Py_INCREF(key);
`
3688
``
`-
Py_INCREF(value);
`
3689
``
`-
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
3690
``
`-
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3691
3706
`return result;
`
3692
3707
``
3693
3708
`fail:
`
`@@ -4180,6 +4195,7 @@ dictitems_iter(_PyDictViewObject *dv)
`
4180
4195
`static int
`
4181
4196
`dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
`
4182
4197
`{
`
``
4198
`+
int result;
`
4183
4199
`PyObject *key, *value, *found;
`
4184
4200
`if (dv->dv_dict == NULL)
`
4185
4201
`return 0;
`
`@@ -4193,7 +4209,10 @@ dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
`
4193
4209
`return -1;
`
4194
4210
`return 0;
`
4195
4211
` }
`
4196
``
`-
return PyObject_RichCompareBool(value, found, Py_EQ);
`
``
4212
`+
Py_INCREF(found);
`
``
4213
`+
result = PyObject_RichCompareBool(value, found, Py_EQ);
`
``
4214
`+
Py_DECREF(found);
`
``
4215
`+
return result;
`
4197
4216
`}
`
4198
4217
``
4199
4218
`static PySequenceMethods dictitems_as_sequence = {
`