Skip to content

Commit 38f0114

Browse files
[3.14] gh-143635: Fix crash in ga_repr_items_list (GH-143670) (#143851)
gh-143635: Fix crash in `ga_repr_items_list` (GH-143670) (cherry picked from commit bdba5f0) Co-authored-by: sobolevn <mail@sobolevn.me>
1 parent fd174d7 commit 38f0114

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
@@ -244,6 +244,56 @@ class MyGeneric:
244244
self.assertEndsWith(repr(MyGeneric[[]]), 'MyGeneric[[]]')
245245
self.assertEndsWith(repr(MyGeneric[[int, str]]), 'MyGeneric[[int, str]]')
246246

247+
def test_evil_repr1(self):
248+
# gh-143635
249+
class Zap:
250+
def __init__(self, container):
251+
self.container = container
252+
def __getattr__(self, name):
253+
if name == "__origin__":
254+
self.container.clear()
255+
return None
256+
if name == "__args__":
257+
return ()
258+
raise AttributeError
259+
260+
params = []
261+
params.append(Zap(params))
262+
alias = GenericAlias(list, (params,))
263+
repr_str = repr(alias)
264+
self.assertTrue(repr_str.startswith("list[["), repr_str)
265+
266+
def test_evil_repr2(self):
267+
class Zap:
268+
def __init__(self, container):
269+
self.container = container
270+
def __getattr__(self, name):
271+
if name == "__qualname__":
272+
self.container.clear()
273+
return "abcd"
274+
if name == "__module__":
275+
return None
276+
raise AttributeError
277+
278+
params = []
279+
params.append(Zap(params))
280+
alias = GenericAlias(list, (params,))
281+
repr_str = repr(alias)
282+
self.assertTrue(repr_str.startswith("list[["), repr_str)
283+
284+
def test_evil_repr3(self):
285+
# gh-143823
286+
lst = []
287+
class X:
288+
def __repr__(self):
289+
lst.clear()
290+
return "x"
291+
292+
lst += [X(), 1]
293+
ga = GenericAlias(int, lst)
294+
with self.assertRaises(IndexError):
295+
repr(ga)
296+
247297
def test_exposed_type(self):
248298
import types
249299
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)