Skip to content

Commit aa5ad50

Browse files
authored
[3.13] gh-143635: Fix crash in ga_repr_items_list (GH-143670) (#143852)
(cherry picked from commit bdba5f0)
1 parent 149ecbb commit aa5ad50

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
@@ -232,6 +232,56 @@ class MyGeneric:
232232
self.assertTrue(repr(MyGeneric[[]]).endswith('MyGeneric[[]]'))
233233
self.assertTrue(repr(MyGeneric[[int, str]]).endswith('MyGeneric[[int, str]]'))
234234

235+
def test_evil_repr1(self):
236+
# gh-143635
237+
class Zap:
238+
def __init__(self, container):
239+
self.container = container
240+
def __getattr__(self, name):
241+
if name == "__origin__":
242+
self.container.clear()
243+
return None
244+
if name == "__args__":
245+
return ()
246+
raise AttributeError
247+
248+
params = []
249+
params.append(Zap(params))
250+
alias = GenericAlias(list, (params,))
251+
repr_str = repr(alias)
252+
self.assertTrue(repr_str.startswith("list[["), repr_str)
253+
254+
def test_evil_repr2(self):
255+
class Zap:
256+
def __init__(self, container):
257+
self.container = container
258+
def __getattr__(self, name):
259+
if name == "__qualname__":
260+
self.container.clear()
261+
return "abcd"
262+
if name == "__module__":
263+
return None
264+
raise AttributeError
265+
266+
params = []
267+
params.append(Zap(params))
268+
alias = GenericAlias(list, (params,))
269+
repr_str = repr(alias)
270+
self.assertTrue(repr_str.startswith("list[["), repr_str)
271+
272+
def test_evil_repr3(self):
273+
# gh-143823
274+
lst = []
275+
class X:
276+
def __repr__(self):
277+
lst.clear()
278+
return "x"
279+
280+
lst += [X(), 1]
281+
ga = GenericAlias(int, lst)
282+
with self.assertRaises(IndexError):
283+
repr(ga)
284+
235285
def test_exposed_type(self):
236286
import types
237287
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
@@ -133,10 +133,15 @@ ga_repr_items_list(_PyUnicodeWriter *writer, PyObject *p)
133133
return -1;
134134
}
135135
}
136-
PyObject *item = PyList_GET_ITEM(p, i);
136+
PyObject *item = PyList_GetItemRef(p, i);
137+
if (item == NULL) {
138+
return -1; // list can be mutated in a callback
139+
}
137140
if (ga_repr_item(writer, item) < 0) {
141+
Py_DECREF(item);
138142
return -1;
139143
}
144+
Py_DECREF(item);
140145
}
141146

142147
if (_PyUnicodeWriter_WriteASCIIString(writer, "]", 1) < 0) {

0 commit comments

Comments
 (0)