diff options
author | 2019-02-13 12:31:56 +0100 | |
---|---|---|
committer | 2019-02-13 12:31:56 +0100 | |
commit | dcb68f47f74b0cc8a1896d4a4c5a6b83c0bbeeae (patch) | |
tree | a59fd0f3445f533933c444eba052adefbeb7cf80 /Objects/sliceobject.c | |
parent | bpo-18283: Add support for bytes to shutil.which (GH-11818) (diff) | |
download | cpython-dcb68f47f74b0cc8a1896d4a4c5a6b83c0bbeeae.tar.gz cpython-dcb68f47f74b0cc8a1896d4a4c5a6b83c0bbeeae.tar.bz2 cpython-dcb68f47f74b0cc8a1896d4a4c5a6b83c0bbeeae.zip |
bpo-35961: Fix a crash in slice_richcompare() (GH-11830)
Fix a crash in slice_richcompare(): use strong references rather than
stolen references for the two temporary internal tuples.
The crash (or assertion error) occurred if a garbage collection
occurred during slice_richcompare(), especially while calling
PyObject_RichCompare(t1, t2, op).
Diffstat (limited to 'Objects/sliceobject.c')
-rw-r--r-- | Objects/sliceobject.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index c60483ea94..2dcb44fdee 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -565,14 +565,11 @@ static PyMethodDef slice_methods[] = { static PyObject * slice_richcompare(PyObject *v, PyObject *w, int op) { - PyObject *t1; - PyObject *t2; - PyObject *res; - if (!PySlice_Check(v) || !PySlice_Check(w)) Py_RETURN_NOTIMPLEMENTED; if (v == w) { + PyObject *res; /* XXX Do we really need this shortcut? There's a unit test for it, but is that fair? */ switch (op) { @@ -589,34 +586,27 @@ slice_richcompare(PyObject *v, PyObject *w, int op) return res; } - t1 = PyTuple_New(3); - if (t1 == NULL) + + PyObject *t1 = PyTuple_Pack(3, + ((PySliceObject *)v)->start, + ((PySliceObject *)v)->stop, + ((PySliceObject *)v)->step); + if (t1 == NULL) { return NULL; - t2 = PyTuple_New(3); + } + + PyObject *t2 = PyTuple_Pack(3, + ((PySliceObject *)w)->start, + ((PySliceObject *)w)->stop, + ((PySliceObject *)w)->step); if (t2 == NULL) { Py_DECREF(t1); return NULL; } - PyTuple_SET_ITEM(t1, 0, ((PySliceObject *)v)->start); - PyTuple_SET_ITEM(t1, 1, ((PySliceObject *)v)->stop); - PyTuple_SET_ITEM(t1, 2, ((PySliceObject *)v)->step); - PyTuple_SET_ITEM(t2, 0, ((PySliceObject *)w)->start); - PyTuple_SET_ITEM(t2, 1, ((PySliceObject *)w)->stop); - PyTuple_SET_ITEM(t2, 2, ((PySliceObject *)w)->step); - - res = PyObject_RichCompare(t1, t2, op); - - PyTuple_SET_ITEM(t1, 0, NULL); - PyTuple_SET_ITEM(t1, 1, NULL); - PyTuple_SET_ITEM(t1, 2, NULL); - PyTuple_SET_ITEM(t2, 0, NULL); - PyTuple_SET_ITEM(t2, 1, NULL); - PyTuple_SET_ITEM(t2, 2, NULL); - + PyObject *res = PyObject_RichCompare(t1, t2, op); Py_DECREF(t1); Py_DECREF(t2); - return res; } |