Skip to content

Commit bdba5f0

Browse files
authored
gh-143635: Fix crash in ga_repr_items_list (#143670)
1 parent 794f758 commit bdba5f0

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

Lib/test/test_genericalias.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,56 @@ class MyGeneric:
245245
self.assertEndsWith(repr(MyGeneric[[]]), 'MyGeneric[[]]')
246246
self.assertEndsWith(repr(MyGeneric[[int, str]]), 'MyGeneric[[int, str]]')
247247

248+
def test_evil_repr1(self):
249+
# gh-143635
250+
class Zap:
251+
def __init__(self, container):
252+
self.container = container
253+
def __getattr__(self, name):
254+
if name == "__origin__":
255+
self.container.clear()
256+
return None
257+
if name == "__args__":
258+
return ()
259+
raise AttributeError
260+
261+
params = []
262+
params.append(Zap(params))
263+
alias = GenericAlias(list, (params,))
264+
repr_str = repr(alias)
265+
self.assertTrue(repr_str.startswith("list[["), repr_str)
266+
267+
def test_evil_repr2(self):
268+
class Zap:
269+
def __init__(self, container):
270+
self.container = container
271+
def __getattr__(self, name):
272+
if name == "__qualname__":
273+
self.container.clear()
274+
return "abcd"
275+
if name == "__module__":
276+
return None
277+
raise AttributeError
278+
279+
params = []
280+
params.append(Zap(params))
281+
alias = GenericAlias(list, (params,))
282+
repr_str = repr(alias)
283+
self.assertTrue(repr_str.startswith("list[["), repr_str)
284+
285+
def test_evil_repr3(self):
286+
# gh-143823
287+
lst = []
288+
class X:
289+
def __repr__(self):
290+
lst.clear()
291+
return "x"
292+
293+
lst += [X(), 1]
294+
ga = GenericAlias(int, lst)
295+
with self.assertRaises(IndexError):
296+
repr(ga)
297+
248298
def test_exposed_type(self):
249299
import types
250300
a = types.GenericAlias(list, int)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixes a crash in ``ga_repr_items_list`` function.

Objects/genericaliasobject.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,15 @@ ga_repr_items_list(PyUnicodeWriter *writer, PyObject *p)
6868
return -1;
6969
}
7070
}
71-
PyObject *item = PyList_GET_ITEM(p, i);
71+
PyObject *item = PyList_GetItemRef(p, i);
72+
if (item == NULL) {
73+
return -1; // list can be mutated in a callback
74+
}
7275
if (_Py_typing_type_repr(writer, item) < 0) {
76+
Py_DECREF(item);
7377
return -1;
7478
}
79+
Py_DECREF(item);
7580
}
7681

7782
if (PyUnicodeWriter_WriteChar(writer, ']') < 0) {

0 commit comments

Comments
 (0)