Skip to content

Commit 4e08352

Browse files
committed
Fix the third crash
1 parent 0eee5b8 commit 4e08352

4 files changed

Lines changed: 23 additions & 8 deletions

File tree

Lib/test/test_genericalias.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def __getattr__(self, name):
259259

260260
params = []
261261
params.append(Zap(params))
262-
alias = type(list[int])(list, (params,))
262+
alias = GenericAlias(list, (params,))
263263
repr_str = repr(alias)
264264
self.assertTrue(repr_str.startswith("list[["), repr_str)
265265

@@ -277,10 +277,23 @@ def __getattr__(self, name):
277277

278278
params = []
279279
params.append(Zap(params))
280-
alias = type(list[int])(list, (params,))
280+
alias = GenericAlias(list, (params,))
281281
repr_str = repr(alias)
282282
self.assertTrue(repr_str.startswith("list[["), repr_str)
283283

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+
284297
def test_exposed_type(self):
285298
import types
286299
a = types.GenericAlias(list, int)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Fixes a crash in ``_Py_typing_type_repr`` function.
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) {

Objects/typevarobject.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,13 @@ _Py_typing_type_repr(PyUnicodeWriter *writer, PyObject *p)
270270
if (p == Py_Ellipsis) {
271271
// The Ellipsis object
272272
r = PyUnicode_FromString("...");
273-
goto cleanup;
273+
goto exit;
274274
}
275275

276276
if (p == (PyObject *)&_PyNone_Type) {
277277
return PyUnicodeWriter_WriteASCII(writer, "None", 4);
278278
}
279279

280-
Py_INCREF(p); // gh-143635
281280
if ((rc = PyObject_HasAttrWithError(p, &_Py_ID(__origin__))) > 0 &&
282281
(rc = PyObject_HasAttrWithError(p, &_Py_ID(__args__))) > 0)
283282
{
@@ -317,8 +316,6 @@ _Py_typing_type_repr(PyUnicodeWriter *writer, PyObject *p)
317316
use_repr:
318317
r = PyObject_Repr(p);
319318
exit:
320-
Py_DECREF(p); // gh-143635
321-
cleanup:
322319
Py_XDECREF(qualname);
323320
Py_XDECREF(module);
324321
if (r == NULL) {

0 commit comments

Comments
 (0)