]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 9 Feb 2020 08:39:28 +0000 (00:39 -0800)
committerGitHub <noreply@github.com>
Sun, 9 Feb 2020 08:39:28 +0000 (00:39 -0800)
(cherry picked from commit c6dedde160a9fce5d049e860f586ad8f93aec822)

Co-authored-by: sweeneyde <36520290+sweeneyde@users.noreply.github.com>
Co-authored-by: sweeneyde <36520290+sweeneyde@users.noreply.github.com>
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 45169ecd11af00dbde01528981a040f25d2b8f12..cc2b90eaa283ea3f704e1a3f593dfcb32ffba642 100644 (file)
@@ -966,7 +966,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;
@@ -1003,7 +1005,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;
         }