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 = {

`