]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421)
authorsweeneyde <36520290+sweeneyde@users.noreply.github.com>
Sun, 9 Feb 2020 08:16:43 +0000 (03:16 -0500)
committerGitHub <noreply@github.com>
Sun, 9 Feb 2020 08:16:43 +0000 (00:16 -0800)
Lib/test/test_deque.py
Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst [new file with mode: 0644]
Modules/_collectionsmodule.c

index 51b66b76aca91d03540db2e05aa80e7fc55af073..c0f7138254f3f6f493314fd1fcbccc80a0c74a64 100644 (file)
@@ -183,6 +183,18 @@ class TestBasic(unittest.TestCase):
         with self.assertRaises(RuntimeError):
             n in d
 
+    def test_contains_count_stop_crashes(self):
+        class A:
+            def __eq__(self, other):
+                d.clear()
+                return NotImplemented
+        d = deque([A(), A()])
+        with self.assertRaises(RuntimeError):
+            _ = 3 in d
+        d = deque([A(), A()])
+        with self.assertRaises(RuntimeError):
+            _ = d.count(3)
+
     def test_extend(self):
         d = deque('a')
         self.assertRaises(TypeError, d.extend, 1)
diff --git a/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst
new file mode 100644 (file)
index 0000000..6862502
--- /dev/null
@@ -0,0 +1 @@
+Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes.
\ No newline at end of file
index 10030606711e0167e583a6946e5cff767f839a80..25e4c96943e464f5d9310c039578e16127aa2ff1 100644 (file)
@@ -965,7 +965,9 @@ deque_count(dequeobject *deque, PyObject *v)
     while (--n >= 0) {
         CHECK_NOT_END(b);
         item = b->data[index];
+        Py_INCREF(item);
         cmp = PyObject_RichCompareBool(item, v, Py_EQ);
+        Py_DECREF(item);
         if (cmp < 0)
             return NULL;
         count += cmp;
@@ -1002,7 +1004,9 @@ deque_contains(dequeobject *deque, PyObject *v)
     while (--n >= 0) {
         CHECK_NOT_END(b);
         item = b->data[index];
+        Py_INCREF(item);
         cmp = PyObject_RichCompareBool(item, v, Py_EQ);
+        Py_DECREF(item);
         if (cmp) {
             return cmp;
         }