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

`