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

`