[2.7] bpo-27945: Fixed various segfaults with dict. (GH-1657) (#1681) · python/cpython@e6a0b59 (original) (raw)

`@@ -1595,11 +1595,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)

`

1595

1595

`/* Update/merge with this (key, value) pair. */

`

1596

1596

`key = PySequence_Fast_GET_ITEM(fast, 0);

`

1597

1597

`value = PySequence_Fast_GET_ITEM(fast, 1);

`

``

1598

`+

Py_INCREF(key);

`

``

1599

`+

Py_INCREF(value);

`

1598

1600

`if (override || PyDict_GetItem(d, key) == NULL) {

`

1599

1601

`int status = PyDict_SetItem(d, key, value);

`

1600

``

`-

if (status < 0)

`

``

1602

`+

if (status < 0) {

`

``

1603

`+

Py_DECREF(key);

`

``

1604

`+

Py_DECREF(value);

`

1601

1605

` goto Fail;

`

``

1606

`+

}

`

1602

1607

` }

`

``

1608

`+

Py_DECREF(key);

`

``

1609

`+

Py_DECREF(value);

`

1603

1610

`Py_DECREF(fast);

`

1604

1611

`Py_DECREF(item);

`

1605

1612

` }

`

`@@ -1938,12 +1945,13 @@ dict_equal(PyDictObject *a, PyDictObject *b)

`

1938

1945

`/* ditto for key */

`

1939

1946

`Py_INCREF(key);

`

1940

1947

`bval = PyDict_GetItem((PyObject *)b, key);

`

1941

``

`-

Py_DECREF(key);

`

1942

1948

`if (bval == NULL) {

`

``

1949

`+

Py_DECREF(key);

`

1943

1950

`Py_DECREF(aval);

`

1944

1951

`return 0;

`

1945

1952

` }

`

1946

1953

`cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);

`

``

1954

`+

Py_DECREF(key);

`

1947

1955

`Py_DECREF(aval);

`

1948

1956

`if (cmp <= 0) /* error or not equal */

`

1949

1957

`return cmp;

`

`@@ -2743,7 +2751,7 @@ PyTypeObject PyDictIterValue_Type = {

`

2743

2751

``

2744

2752

`static PyObject *dictiter_iternextitem(dictiterobject *di)

`

2745

2753

`{

`

2746

``

`-

PyObject *key, *value, *result = di->di_result;

`

``

2754

`+

PyObject *key, *value, *result;

`

2747

2755

` register Py_ssize_t i, mask;

`

2748

2756

` register PyDictEntry *ep;

`

2749

2757

`PyDictObject *d = di->di_dict;

`

`@@ -2770,22 +2778,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)

`

2770

2778

`if (i > mask)

`

2771

2779

` goto fail;

`

2772

2780

``

2773

``

`-

if (result->ob_refcnt == 1) {

`

``

2781

`+

di->len--;

`

``

2782

`+

key = ep[i].me_key;

`

``

2783

`+

value = ep[i].me_value;

`

``

2784

`+

Py_INCREF(key);

`

``

2785

`+

Py_INCREF(value);

`

``

2786

`+

result = di->di_result;

`

``

2787

`+

if (Py_REFCNT(result) == 1) {

`

``

2788

`+

PyObject *oldkey = PyTuple_GET_ITEM(result, 0);

`

``

2789

`+

PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);

`

``

2790

`+

PyTuple_SET_ITEM(result, 0, key); /* steals reference */

`

``

2791

`+

PyTuple_SET_ITEM(result, 1, value); /* steals reference */

`

2774

2792

`Py_INCREF(result);

`

2775

``

`-

Py_DECREF(PyTuple_GET_ITEM(result, 0));

`

2776

``

`-

Py_DECREF(PyTuple_GET_ITEM(result, 1));

`

``

2793

`+

Py_DECREF(oldkey);

`

``

2794

`+

Py_DECREF(oldvalue);

`

2777

2795

` } else {

`

2778

2796

`result = PyTuple_New(2);

`

2779

2797

`if (result == NULL)

`

2780

2798

`return NULL;

`

``

2799

`+

PyTuple_SET_ITEM(result, 0, key); /* steals reference */

`

``

2800

`+

PyTuple_SET_ITEM(result, 1, value); /* steals reference */

`

2781

2801

` }

`

2782

``

`-

di->len--;

`

2783

``

`-

key = ep[i].me_key;

`

2784

``

`-

value = ep[i].me_value;

`

2785

``

`-

Py_INCREF(key);

`

2786

``

`-

Py_INCREF(value);

`

2787

``

`-

PyTuple_SET_ITEM(result, 0, key);

`

2788

``

`-

PyTuple_SET_ITEM(result, 1, value);

`

2789

2802

`return result;

`

2790

2803

``

2791

2804

`fail:

`

`@@ -3186,6 +3199,7 @@ dictitems_iter(dictviewobject *dv)

`

3186

3199

`static int

`

3187

3200

`dictitems_contains(dictviewobject *dv, PyObject *obj)

`

3188

3201

`{

`

``

3202

`+

int result;

`

3189

3203

`PyObject *key, *value, *found;

`

3190

3204

`if (dv->dv_dict == NULL)

`

3191

3205

`return 0;

`

`@@ -3199,7 +3213,10 @@ dictitems_contains(dictviewobject *dv, PyObject *obj)

`

3199

3213

`return -1;

`

3200

3214

`return 0;

`

3201

3215

` }

`

3202

``

`-

return PyObject_RichCompareBool(value, found, Py_EQ);

`

``

3216

`+

Py_INCREF(found);

`

``

3217

`+

result = PyObject_RichCompareBool(value, found, Py_EQ);

`

``

3218

`+

Py_DECREF(found);

`

``

3219

`+

return result;

`

3203

3220

`}

`

3204

3221

``

3205

3222

`static PySequenceMethods dictitems_as_sequence = {

`