diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 9df9296e26ad5c..2f0d929900e9fe 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -244,6 +244,56 @@ class MyGeneric: self.assertEndsWith(repr(MyGeneric[[]]), 'MyGeneric[[]]') self.assertEndsWith(repr(MyGeneric[[int, str]]), 'MyGeneric[[int, str]]') + def test_evil_repr1(self): + # gh-143635 + class Zap: + def __init__(self, container): + self.container = container + def __getattr__(self, name): + if name == "__origin__": + self.container.clear() + return None + if name == "__args__": + return () + raise AttributeError + + params = [] + params.append(Zap(params)) + alias = GenericAlias(list, (params,)) + repr_str = repr(alias) + self.assertTrue(repr_str.startswith("list[["), repr_str) + + def test_evil_repr2(self): + class Zap: + def __init__(self, container): + self.container = container + def __getattr__(self, name): + if name == "__qualname__": + self.container.clear() + return "abcd" + if name == "__module__": + return None + raise AttributeError + + params = [] + params.append(Zap(params)) + alias = GenericAlias(list, (params,)) + repr_str = repr(alias) + self.assertTrue(repr_str.startswith("list[["), repr_str) + + def test_evil_repr3(self): + # gh-143823 + lst = [] + class X: + def __repr__(self): + lst.clear() + return "x" + + lst += [X(), 1] + ga = GenericAlias(int, lst) + with self.assertRaises(IndexError): + repr(ga) + def test_exposed_type(self): import types a = types.GenericAlias(list, int) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst new file mode 100644 index 00000000000000..4ce0e71a47e145 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst @@ -0,0 +1 @@ +Fixes a crash in ``ga_repr_items_list`` function. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 8b526f43f1e053..119dd4b5c2dd00 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -68,10 +68,15 @@ ga_repr_items_list(PyUnicodeWriter *writer, PyObject *p) return -1; } } - PyObject *item = PyList_GET_ITEM(p, i); + PyObject *item = PyList_GetItemRef(p, i); + if (item == NULL) { + return -1; // list can be mutated in a callback + } if (_Py_typing_type_repr(writer, item) < 0) { + Py_DECREF(item); return -1; } + Py_DECREF(item); } if (PyUnicodeWriter_WriteChar(writer, ']') < 0) {