[3.3] [3.5] bpo-27945: Fixed various segfaults with dict. (GH-1657) (… · python/cpython@8fbdab5 (original) (raw)

`@@ -810,56 +810,62 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)

`

810

810

`PyDictKeyEntry *ep;

`

811

811

`assert(key != dummy);

`

812

812

``

``

813

`+

Py_INCREF(key);

`

``

814

`+

Py_INCREF(value);

`

813

815

`if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {

`

814

816

`if (insertion_resize(mp) < 0)

`

815

``

`-

return -1;

`

``

817

`+

goto Fail;

`

816

818

` }

`

817

819

``

818

820

`ep = mp->ma_keys->dk_lookup(mp, key, hash, &value_addr);

`

819

``

`-

if (ep == NULL) {

`

820

``

`-

return -1;

`

821

``

`-

}

`

822

``

`-

Py_INCREF(value);

`

``

821

`+

if (ep == NULL)

`

``

822

`+

goto Fail;

`

``

823

+

823

824

`MAINTAIN_TRACKING(mp, key, value);

`

824

825

`old_value = *value_addr;

`

825

826

`if (old_value != NULL) {

`

826

827

`assert(ep->me_key != NULL && ep->me_key != dummy);

`

827

828

`*value_addr = value;

`

828

``

`-

Py_DECREF(old_value); /* which CAN re-enter */

`

``

829

`+

Py_DECREF(old_value); /* which CAN re-enter (see issue #22653) */

`

``

830

`+

Py_DECREF(key);

`

829

831

` }

`

830

832

`else {

`

831

833

`if (ep->me_key == NULL) {

`

832

``

`-

Py_INCREF(key);

`

833

834

`if (mp->ma_keys->dk_usable <= 0) {

`

834

835

`/* Need to resize. */

`

835

``

`-

if (insertion_resize(mp) < 0) {

`

836

``

`-

Py_DECREF(key);

`

837

``

`-

Py_DECREF(value);

`

838

``

`-

return -1;

`

839

``

`-

}

`

``

836

`+

if (insertion_resize(mp) < 0)

`

``

837

`+

goto Fail;

`

840

838

`ep = find_empty_slot(mp, key, hash, &value_addr);

`

841

839

` }

`

``

840

`+

mp->ma_used++;

`

``

841

`+

*value_addr = value;

`

842

842

`mp->ma_keys->dk_usable--;

`

843

843

`assert(mp->ma_keys->dk_usable >= 0);

`

844

844

`ep->me_key = key;

`

845

845

`ep->me_hash = hash;

`

``

846

`+

assert(ep->me_key != NULL && ep->me_key != dummy);

`

846

847

` }

`

847

848

`else {

`

``

849

`+

mp->ma_used++;

`

``

850

`+

*value_addr = value;

`

848

851

`if (ep->me_key == dummy) {

`

849

``

`-

Py_INCREF(key);

`

850

852

`ep->me_key = key;

`

851

853

`ep->me_hash = hash;

`

852

854

`Py_DECREF(dummy);

`

853

855

` } else {

`

854

856

`assert(_PyDict_HasSplitTable(mp));

`

``

857

`+

Py_DECREF(key);

`

855

858

` }

`

856

859

` }

`

857

``

`-

mp->ma_used++;

`

858

``

`-

*value_addr = value;

`

859

860

` }

`

860

861

`assert(ep->me_key != NULL && ep->me_key != dummy);

`

861

862

`assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);

`

862

863

`return 0;

`

``

864

+

``

865

`+

Fail:

`

``

866

`+

Py_DECREF(value);

`

``

867

`+

Py_DECREF(key);

`

``

868

`+

return -1;

`

863

869

`}

`

864

870

``

865

871

`/*

`

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

`

1879

1885

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

`

1880

1886

`key = PySequence_Fast_GET_ITEM(fast, 0);

`

1881

1887

`value = PySequence_Fast_GET_ITEM(fast, 1);

`

``

1888

`+

Py_INCREF(key);

`

``

1889

`+

Py_INCREF(value);

`

1882

1890

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

`

1883

1891

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

`

1884

``

`-

if (status < 0)

`

``

1892

`+

if (status < 0) {

`

``

1893

`+

Py_DECREF(key);

`

``

1894

`+

Py_DECREF(value);

`

1885

1895

` goto Fail;

`

``

1896

`+

}

`

1886

1897

` }

`

``

1898

`+

Py_DECREF(key);

`

``

1899

`+

Py_DECREF(value);

`

1887

1900

`Py_DECREF(fast);

`

1888

1901

`Py_DECREF(item);

`

1889

1902

` }

`

`@@ -2137,14 +2150,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)

`

2137

2150

`/* ditto for key */

`

2138

2151

`Py_INCREF(key);

`

2139

2152

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

`

2140

``

`-

Py_DECREF(key);

`

2141

2153

`if (bval == NULL) {

`

``

2154

`+

Py_DECREF(key);

`

2142

2155

`Py_DECREF(aval);

`

2143

2156

`if (PyErr_Occurred())

`

2144

2157

`return -1;

`

2145

2158

`return 0;

`

2146

2159

` }

`

2147

2160

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

`

``

2161

`+

Py_DECREF(key);

`

2148

2162

`Py_DECREF(aval);

`

2149

2163

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

`

2150

2164

`return cmp;

`

`@@ -2970,7 +2984,7 @@ PyTypeObject PyDictIterValue_Type = {

`

2970

2984

``

2971

2985

`static PyObject *dictiter_iternextitem(dictiterobject *di)

`

2972

2986

`{

`

2973

``

`-

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

`

``

2987

`+

PyObject *key, *value, *result;

`

2974

2988

` register Py_ssize_t i, mask, offset;

`

2975

2989

`PyDictObject *d = di->di_dict;

`

2976

2990

`PyObject **value_ptr;

`

`@@ -3006,22 +3020,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)

`

3006

3020

`if (i > mask)

`

3007

3021

` goto fail;

`

3008

3022

``

3009

``

`-

if (result->ob_refcnt == 1) {

`

``

3023

`+

di->len--;

`

``

3024

`+

key = d->ma_keys->dk_entries[i].me_key;

`

``

3025

`+

value = *value_ptr;

`

``

3026

`+

Py_INCREF(key);

`

``

3027

`+

Py_INCREF(value);

`

``

3028

`+

result = di->di_result;

`

``

3029

`+

if (Py_REFCNT(result) == 1) {

`

``

3030

`+

PyObject *oldkey = PyTuple_GET_ITEM(result, 0);

`

``

3031

`+

PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);

`

``

3032

`+

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

`

``

3033

`+

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

`

3010

3034

`Py_INCREF(result);

`

3011

``

`-

Py_DECREF(PyTuple_GET_ITEM(result, 0));

`

3012

``

`-

Py_DECREF(PyTuple_GET_ITEM(result, 1));

`

``

3035

`+

Py_DECREF(oldkey);

`

``

3036

`+

Py_DECREF(oldvalue);

`

3013

3037

` } else {

`

3014

3038

`result = PyTuple_New(2);

`

3015

3039

`if (result == NULL)

`

3016

3040

`return NULL;

`

``

3041

`+

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

`

``

3042

`+

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

`

3017

3043

` }

`

3018

``

`-

di->len--;

`

3019

``

`-

key = d->ma_keys->dk_entries[i].me_key;

`

3020

``

`-

value = *value_ptr;

`

3021

``

`-

Py_INCREF(key);

`

3022

``

`-

Py_INCREF(value);

`

3023

``

`-

PyTuple_SET_ITEM(result, 0, key);

`

3024

``

`-

PyTuple_SET_ITEM(result, 1, value);

`

3025

3044

`return result;

`

3026

3045

``

3027

3046

`fail:

`

`@@ -3521,6 +3540,7 @@ dictitems_iter(dictviewobject *dv)

`

3521

3540

`static int

`

3522

3541

`dictitems_contains(dictviewobject *dv, PyObject *obj)

`

3523

3542

`{

`

``

3543

`+

int result;

`

3524

3544

`PyObject *key, *value, *found;

`

3525

3545

`if (dv->dv_dict == NULL)

`

3526

3546

`return 0;

`

`@@ -3534,7 +3554,10 @@ dictitems_contains(dictviewobject *dv, PyObject *obj)

`

3534

3554

`return -1;

`

3535

3555

`return 0;

`

3536

3556

` }

`

3537

``

`-

return PyObject_RichCompareBool(value, found, Py_EQ);

`

``

3557

`+

Py_INCREF(found);

`

``

3558

`+

result = PyObject_RichCompareBool(value, found, Py_EQ);

`

``

3559

`+

Py_DECREF(found);

`

``

3560

`+

return result;

`

3538

3561

`}

`

3539

3562

``

3540

3563

`static PySequenceMethods dictitems_as_sequence = {

`