]> granicus.if.org Git - python/commitdiff
bpo-35961: Fix a crash in slice_richcompare() (GH-11830)
authorVictor Stinner <vstinner@redhat.com>
Wed, 13 Feb 2019 11:31:56 +0000 (12:31 +0100)
committerGitHub <noreply@github.com>
Wed, 13 Feb 2019 11:31:56 +0000 (12:31 +0100)
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).

Misc/NEWS.d/next/Core and Builtins/2019-02-12-20-16-34.bpo-35961.7f7Sne.rst [new file with mode: 0644]
Objects/sliceobject.c

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 (file)
index 0000000..943aaa2
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a crash in slice_richcompare(): use strong references rather than stolen
+references for the two temporary internal tuples.
index c60483ea949459284ebaa99901a463add5785d21..2dcb44fdee57ed0c69356bcc7564eca3f5c4a5a6 100644 (file)
@@ -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;
 }