bpo-27945: Fixed various segfaults with dict. (#1657) · python/cpython@753bca3 (original) (raw)
`@@ -1107,18 +1107,18 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1107
1107
`PyDictKeyEntry *ep;
`
1108
1108
`Py_ssize_t hashpos, ix;
`
1109
1109
``
``
1110
`+
Py_INCREF(key);
`
``
1111
`+
Py_INCREF(value);
`
1110
1112
`if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
`
1111
1113
`if (insertion_resize(mp) < 0)
`
1112
``
`-
return -1;
`
``
1114
`+
goto Fail;
`
1113
1115
` }
`
1114
1116
``
1115
1117
`ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value, &hashpos);
`
1116
``
`-
if (ix == DKIX_ERROR) {
`
1117
``
`-
return -1;
`
1118
``
`-
}
`
``
1118
`+
if (ix == DKIX_ERROR)
`
``
1119
`+
goto Fail;
`
1119
1120
``
1120
1121
`assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
`
1121
``
`-
Py_INCREF(value);
`
1122
1122
`MAINTAIN_TRACKING(mp, key, value);
`
1123
1123
``
1124
1124
`/* When insertion order is different from shared key, we can't share
`
`@@ -1127,10 +1127,8 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1127
1127
`if (_PyDict_HasSplitTable(mp) &&
`
1128
1128
` ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
`
1129
1129
` (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
`
1130
``
`-
if (insertion_resize(mp) < 0) {
`
1131
``
`-
Py_DECREF(value);
`
1132
``
`-
return -1;
`
1133
``
`-
}
`
``
1130
`+
if (insertion_resize(mp) < 0)
`
``
1131
`+
goto Fail;
`
1134
1132
`hashpos = find_empty_slot(mp->ma_keys, key, hash);
`
1135
1133
`ix = DKIX_EMPTY;
`
1136
1134
` }
`
`@@ -1140,15 +1138,12 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1140
1138
`assert(old_value == NULL);
`
1141
1139
`if (mp->ma_keys->dk_usable <= 0) {
`
1142
1140
`/* Need to resize. */
`
1143
``
`-
if (insertion_resize(mp) < 0) {
`
1144
``
`-
Py_DECREF(value);
`
1145
``
`-
return -1;
`
1146
``
`-
}
`
``
1141
`+
if (insertion_resize(mp) < 0)
`
``
1142
`+
goto Fail;
`
1147
1143
`hashpos = find_empty_slot(mp->ma_keys, key, hash);
`
1148
1144
` }
`
1149
1145
`ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
`
1150
1146
`dk_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
`
1151
``
`-
Py_INCREF(key);
`
1152
1147
`ep->me_key = key;
`
1153
1148
`ep->me_hash = hash;
`
1154
1149
`if (mp->ma_values) {
`
`@@ -1183,7 +1178,13 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
`
1183
1178
`mp->ma_version_tag = DICT_NEXT_VERSION();
`
1184
1179
`Py_XDECREF(old_value); /* which CAN re-enter (see issue #22653) */
`
1185
1180
`assert(_PyDict_CheckConsistency(mp));
`
``
1181
`+
Py_DECREF(key);
`
1186
1182
`return 0;
`
``
1183
+
``
1184
`+
Fail:
`
``
1185
`+
Py_DECREF(value);
`
``
1186
`+
Py_DECREF(key);
`
``
1187
`+
return -1;
`
1187
1188
`}
`
1188
1189
``
1189
1190
`/*
`
`@@ -2419,11 +2420,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
`
2419
2420
`/* Update/merge with this (key, value) pair. */
`
2420
2421
`key = PySequence_Fast_GET_ITEM(fast, 0);
`
2421
2422
`value = PySequence_Fast_GET_ITEM(fast, 1);
`
``
2423
`+
Py_INCREF(key);
`
``
2424
`+
Py_INCREF(value);
`
2422
2425
`if (override || PyDict_GetItem(d, key) == NULL) {
`
2423
2426
`int status = PyDict_SetItem(d, key, value);
`
2424
``
`-
if (status < 0)
`
``
2427
`+
if (status < 0) {
`
``
2428
`+
Py_DECREF(key);
`
``
2429
`+
Py_DECREF(value);
`
2425
2430
` goto Fail;
`
``
2431
`+
}
`
2426
2432
` }
`
``
2433
`+
Py_DECREF(key);
`
``
2434
`+
Py_DECREF(value);
`
2427
2435
`Py_DECREF(fast);
`
2428
2436
`Py_DECREF(item);
`
2429
2437
` }
`
`@@ -2720,14 +2728,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)
`
2720
2728
`Py_INCREF(key);
`
2721
2729
`/* reuse the known hash value */
`
2722
2730
`b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval, NULL);
`
2723
``
`-
Py_DECREF(key);
`
2724
2731
`if (bval == NULL) {
`
``
2732
`+
Py_DECREF(key);
`
2725
2733
`Py_DECREF(aval);
`
2726
2734
`if (PyErr_Occurred())
`
2727
2735
`return -1;
`
2728
2736
`return 0;
`
2729
2737
` }
`
2730
2738
`cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
`
``
2739
`+
Py_DECREF(key);
`
2731
2740
`Py_DECREF(aval);
`
2732
2741
`if (cmp <= 0) /* error or not equal */
`
2733
2742
`return cmp;
`
`@@ -3612,7 +3621,7 @@ PyTypeObject PyDictIterValue_Type = {
`
3612
3621
`static PyObject *
`
3613
3622
`dictiter_iternextitem(dictiterobject *di)
`
3614
3623
`{
`
3615
``
`-
PyObject *key, *value, *result = di->di_result;
`
``
3624
`+
PyObject *key, *value, *result;
`
3616
3625
`Py_ssize_t i;
`
3617
3626
`PyDictObject *d = di->di_dict;
`
3618
3627
``
`@@ -3650,20 +3659,25 @@ dictiter_iternextitem(dictiterobject *di)
`
3650
3659
` }
`
3651
3660
`di->di_pos = i+1;
`
3652
3661
`di->len--;
`
3653
``
`-
if (result->ob_refcnt == 1) {
`
``
3662
`+
Py_INCREF(key);
`
``
3663
`+
Py_INCREF(value);
`
``
3664
`+
result = di->di_result;
`
``
3665
`+
if (Py_REFCNT(result) == 1) {
`
``
3666
`+
PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
`
``
3667
`+
PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
`
``
3668
`+
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
``
3669
`+
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3654
3670
`Py_INCREF(result);
`
3655
``
`-
Py_DECREF(PyTuple_GET_ITEM(result, 0));
`
3656
``
`-
Py_DECREF(PyTuple_GET_ITEM(result, 1));
`
``
3671
`+
Py_DECREF(oldkey);
`
``
3672
`+
Py_DECREF(oldvalue);
`
3657
3673
` }
`
3658
3674
`else {
`
3659
3675
`result = PyTuple_New(2);
`
3660
3676
`if (result == NULL)
`
3661
3677
`return NULL;
`
``
3678
`+
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
``
3679
`+
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3662
3680
` }
`
3663
``
`-
Py_INCREF(key);
`
3664
``
`-
Py_INCREF(value);
`
3665
``
`-
PyTuple_SET_ITEM(result, 0, key); /* steals reference */
`
3666
``
`-
PyTuple_SET_ITEM(result, 1, value); /* steals reference */
`
3667
3681
`return result;
`
3668
3682
``
3669
3683
`fail:
`
`@@ -4156,6 +4170,7 @@ dictitems_iter(_PyDictViewObject *dv)
`
4156
4170
`static int
`
4157
4171
`dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
`
4158
4172
`{
`
``
4173
`+
int result;
`
4159
4174
`PyObject *key, *value, *found;
`
4160
4175
`if (dv->dv_dict == NULL)
`
4161
4176
`return 0;
`
`@@ -4169,7 +4184,10 @@ dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
`
4169
4184
`return -1;
`
4170
4185
`return 0;
`
4171
4186
` }
`
4172
``
`-
return PyObject_RichCompareBool(value, found, Py_EQ);
`
``
4187
`+
Py_INCREF(found);
`
``
4188
`+
result = PyObject_RichCompareBool(value, found, Py_EQ);
`
``
4189
`+
Py_DECREF(found);
`
``
4190
`+
return result;
`
4173
4191
`}
`
4174
4192
``
4175
4193
`static PySequenceMethods dictitems_as_sequence = {
`