From: Victor Stinner Date: Wed, 13 Feb 2019 11:31:56 +0000 (+0100) Subject: bpo-35961: Fix a crash in slice_richcompare() (GH-11830) X-Git-Tag: v3.8.0a2~81 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dcb68f47f74b0cc8a1896d4a4c5a6b83c0bbeeae;p=thirdparty%2FPython%2Fcpython.git 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). --- diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-12-20-16-34.bpo-35961.7f7Sne.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-12-20-16-34.bpo-35961.7f7Sne.rst new file mode 100644 index 000000000000..943aaa2f3c80 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-12-20-16-34.bpo-35961.7f7Sne.rst @@ -0,0 +1,2 @@ +Fix a crash in slice_richcompare(): use strong references rather than stolen +references for the two temporary internal tuples. diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index c60483ea9494..2dcb44fdee57 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; }