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