From: sweeneyde <36520290+sweeneyde@users.noreply.github.com> Date: Sun, 9 Feb 2020 08:16:43 +0000 (-0500) Subject: bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421) X-Git-Tag: v3.9.0a4~95 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c6dedde160a9fce5d049e860f586ad8f93aec822;p=thirdparty%2FPython%2Fcpython.git bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421) --- diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 51b66b76aca9..c0f7138254f3 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -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 index 000000000000..68625028fb7a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-02-09-05-51-05.bpo-39590.rf98GU.rst @@ -0,0 +1 @@ +Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes. \ No newline at end of file diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 10030606711e..25e4c96943e4 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -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; }