Skip to content

Commit c6dedde

Browse files
authored
bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421)
1 parent 7f6f7ee commit c6dedde

File tree

3 files changed

+17
-0
lines changed

3 files changed

+17
-0
lines changed

Lib/test/test_deque.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ def test_contains(self):
183183
with self.assertRaises(RuntimeError):
184184
n in d
185185

186+
def test_contains_count_stop_crashes(self):
187+
class A:
188+
def __eq__(self, other):
189+
d.clear()
190+
return NotImplemented
191+
d = deque([A(), A()])
192+
with self.assertRaises(RuntimeError):
193+
_ = 3 in d
194+
d = deque([A(), A()])
195+
with self.assertRaises(RuntimeError):
196+
_ = d.count(3)
197+
186198
def test_extend(self):
187199
d = deque('a')
188200
self.assertRaises(TypeError, d.extend, 1)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes.

Modules/_collectionsmodule.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,9 @@ deque_count(dequeobject *deque, PyObject *v)
965965
while (--n >= 0) {
966966
CHECK_NOT_END(b);
967967
item = b->data[index];
968+
Py_INCREF(item);
968969
cmp = PyObject_RichCompareBool(item, v, Py_EQ);
970+
Py_DECREF(item);
969971
if (cmp < 0)
970972
return NULL;
971973
count += cmp;
@@ -1002,7 +1004,9 @@ deque_contains(dequeobject *deque, PyObject *v)
10021004
while (--n >= 0) {
10031005
CHECK_NOT_END(b);
10041006
item = b->data[index];
1007+
Py_INCREF(item);
10051008
cmp = PyObject_RichCompareBool(item, v, Py_EQ);
1009+
Py_DECREF(item);
10061010
if (cmp) {
10071011
return cmp;
10081012
}

0 commit comments

Comments
 (0)