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

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

`

805

805

`PyDictKeyEntry *ep;

`

806

806

`assert(key != dummy);

`

807

807

``

``

808

`+

Py_INCREF(key);

`

``

809

`+

Py_INCREF(value);

`

808

810

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

`

809

811

`if (insertion_resize(mp) < 0)

`

810

``

`-

return -1;

`

``

812

`+

goto Fail;

`

811

813

` }

`

812

814

``

813

815

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

`

814

``

`-

if (ep == NULL) {

`

815

``

`-

return -1;

`

816

``

`-

}

`

``

816

`+

if (ep == NULL)

`

``

817

`+

goto Fail;

`

``

818

+

817

819

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

`

818

``

`-

Py_INCREF(value);

`

819

820

`MAINTAIN_TRACKING(mp, key, value);

`

820

821

`old_value = *value_addr;

`

821

822

`if (old_value != NULL) {

`

822

823

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

`

823

824

`*value_addr = value;

`

824

825

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

`

``

826

`+

Py_DECREF(key);

`

825

827

` }

`

826

828

`else {

`

827

829

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

`

828

``

`-

Py_INCREF(key);

`

829

830

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

`

830

831

`/* Need to resize. */

`

831

``

`-

if (insertion_resize(mp) < 0) {

`

832

``

`-

Py_DECREF(key);

`

833

``

`-

Py_DECREF(value);

`

834

``

`-

return -1;

`

835

``

`-

}

`

``

832

`+

if (insertion_resize(mp) < 0)

`

``

833

`+

goto Fail;

`

836

834

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

`

837

835

` }

`

``

836

`+

mp->ma_used++;

`

``

837

`+

*value_addr = value;

`

838

838

`mp->ma_keys->dk_usable--;

`

839

839

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

`

840

840

`ep->me_key = key;

`

841

841

`ep->me_hash = hash;

`

``

842

`+

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

`

842

843

` }

`

843

844

`else {

`

``

845

`+

mp->ma_used++;

`

``

846

`+

*value_addr = value;

`

844

847

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

`

845

``

`-

Py_INCREF(key);

`

846

848

`ep->me_key = key;

`

847

849

`ep->me_hash = hash;

`

848

850

`Py_DECREF(dummy);

`

849

851

` } else {

`

850

852

`assert(_PyDict_HasSplitTable(mp));

`

``

853

`+

Py_DECREF(key);

`

851

854

` }

`

852

855

` }

`

853

``

`-

mp->ma_used++;

`

854

``

`-

*value_addr = value;

`

855

``

`-

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

`

856

856

` }

`

857

857

`return 0;

`

``

858

+

``

859

`+

Fail:

`

``

860

`+

Py_DECREF(value);

`

``

861

`+

Py_DECREF(key);

`

``

862

`+

return -1;

`

858

863

`}

`

859

864

``

860

865

`/*

`

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

`

1911

1916

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

`

1912

1917

`key = PySequence_Fast_GET_ITEM(fast, 0);

`

1913

1918

`value = PySequence_Fast_GET_ITEM(fast, 1);

`

``

1919

`+

Py_INCREF(key);

`

``

1920

`+

Py_INCREF(value);

`

1914

1921

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

`

1915

1922

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

`

1916

``

`-

if (status < 0)

`

``

1923

`+

if (status < 0) {

`

``

1924

`+

Py_DECREF(key);

`

``

1925

`+

Py_DECREF(value);

`

1917

1926

` goto Fail;

`

``

1927

`+

}

`

1918

1928

` }

`

``

1929

`+

Py_DECREF(key);

`

``

1930

`+

Py_DECREF(value);

`

1919

1931

`Py_DECREF(fast);

`

1920

1932

`Py_DECREF(item);

`

1921

1933

` }

`

`@@ -2174,14 +2186,15 @@ dict_equal(PyDictObject *a, PyDictObject *b)

`

2174

2186

`bval = NULL;

`

2175

2187

`else

`

2176

2188

`bval = *vaddr;

`

2177

``

`-

Py_DECREF(key);

`

2178

2189

`if (bval == NULL) {

`

``

2190

`+

Py_DECREF(key);

`

2179

2191

`Py_DECREF(aval);

`

2180

2192

`if (PyErr_Occurred())

`

2181

2193

`return -1;

`

2182

2194

`return 0;

`

2183

2195

` }

`

2184

2196

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

`

``

2197

`+

Py_DECREF(key);

`

2185

2198

`Py_DECREF(aval);

`

2186

2199

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

`

2187

2200

`return cmp;

`

`@@ -3046,7 +3059,7 @@ PyTypeObject PyDictIterValue_Type = {

`

3046

3059

``

3047

3060

`static PyObject *dictiter_iternextitem(dictiterobject *di)

`

3048

3061

`{

`

3049

``

`-

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

`

``

3062

`+

PyObject *key, *value, *result;

`

3050

3063

`Py_ssize_t i, mask, offset;

`

3051

3064

`PyDictObject *d = di->di_dict;

`

3052

3065

`PyObject **value_ptr;

`

`@@ -3082,22 +3095,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)

`

3082

3095

`if (i > mask)

`

3083

3096

` goto fail;

`

3084

3097

``

3085

``

`-

if (result->ob_refcnt == 1) {

`

``

3098

`+

di->len--;

`

``

3099

`+

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

`

``

3100

`+

value = *value_ptr;

`

``

3101

`+

Py_INCREF(key);

`

``

3102

`+

Py_INCREF(value);

`

``

3103

`+

result = di->di_result;

`

``

3104

`+

if (Py_REFCNT(result) == 1) {

`

``

3105

`+

PyObject *oldkey = PyTuple_GET_ITEM(result, 0);

`

``

3106

`+

PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);

`

``

3107

`+

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

`

``

3108

`+

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

`

3086

3109

`Py_INCREF(result);

`

3087

``

`-

Py_DECREF(PyTuple_GET_ITEM(result, 0));

`

3088

``

`-

Py_DECREF(PyTuple_GET_ITEM(result, 1));

`

``

3110

`+

Py_DECREF(oldkey);

`

``

3111

`+

Py_DECREF(oldvalue);

`

3089

3112

` } else {

`

3090

3113

`result = PyTuple_New(2);

`

3091

3114

`if (result == NULL)

`

3092

3115

`return NULL;

`

``

3116

`+

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

`

``

3117

`+

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

`

3093

3118

` }

`

3094

``

`-

di->len--;

`

3095

``

`-

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

`

3096

``

`-

value = *value_ptr;

`

3097

``

`-

Py_INCREF(key);

`

3098

``

`-

Py_INCREF(value);

`

3099

``

`-

PyTuple_SET_ITEM(result, 0, key);

`

3100

``

`-

PyTuple_SET_ITEM(result, 1, value);

`

3101

3119

`return result;

`

3102

3120

``

3103

3121

`fail:

`

`@@ -3596,6 +3614,7 @@ dictitems_iter(dictviewobject *dv)

`

3596

3614

`static int

`

3597

3615

`dictitems_contains(dictviewobject *dv, PyObject *obj)

`

3598

3616

`{

`

``

3617

`+

int result;

`

3599

3618

`PyObject *key, *value, *found;

`

3600

3619

`if (dv->dv_dict == NULL)

`

3601

3620

`return 0;

`

`@@ -3609,7 +3628,10 @@ dictitems_contains(dictviewobject *dv, PyObject *obj)

`

3609

3628

`return -1;

`

3610

3629

`return 0;

`

3611

3630

` }

`

3612

``

`-

return PyObject_RichCompareBool(value, found, Py_EQ);

`

``

3631

`+

Py_INCREF(found);

`

``

3632

`+

result = PyObject_RichCompareBool(value, found, Py_EQ);

`

``

3633

`+

Py_DECREF(found);

`

``

3634

`+

return result;

`

3613

3635

`}

`

3614

3636

``

3615

3637

`static PySequenceMethods dictitems_as_sequence = {

`