diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 640ec59145..b90979ac43 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1950,7 +1950,7 @@ unicode_asutf8andsize(PyObject *self, PyObject *args) return NULL; } - buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); + buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); if (buffer == NULL) { return NULL; } @@ -6074,6 +6074,74 @@ static PyTypeObject MethodDescriptor2_Type = { }; + +typedef struct { + PyObject_HEAD + PyObject* dict; + PyObject* weakreflist; + PyObject* func; +} badgc2object; + +static void +badgc2object_dealloc(badgc2object *self) +{ + PyObject *res = PyObject_CallFunctionObjArgs(self->func, NULL); + PyErr_Clear(); + Py_XDECREF(res); + + Py_CLEAR(self->func); + + if (self->weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } + + Py_XDECREF(self->dict); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject* +badgc2object_set_func(badgc2object *self, PyObject *func) +{ + Py_INCREF(func); + self->func = func; + Py_RETURN_NONE; +} + +static PyMethodDef badgc2object_methods[] = { + {"set_func", (PyCFunction)badgc2object_set_func, METH_O, NULL}, + {NULL, NULL} /* sentinel */ +}; + +static int +badgc2object_traverse(badgc2object *self, visitproc visit, void *arg) +{ + Py_VISIT(self->func); + return 0; +} + +static PyTypeObject BadGC2Type = { + /* Don't implement Py_TPFLAGS_HAVE_GC not tp_traverse: + the GC doesn't see the reference to func */ + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "BadGC2Type", + .tp_doc = "Bad GC Type", + .tp_basicsize = sizeof(badgc2object), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + + .tp_new = PyType_GenericNew, + .tp_free = PyObject_GC_Del, + .tp_traverse = (traverseproc)badgc2object_traverse, + + .tp_getattro = PyObject_GenericGetAttr, + .tp_setattro = PyObject_GenericSetAttr, + .tp_dictoffset = offsetof(badgc2object, dict), + .tp_methods = badgc2object_methods, + .tp_dealloc = (destructor) badgc2object_dealloc, + .tp_weaklistoffset = offsetof(badgc2object, weakreflist) +}; + + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, "_testcapi", @@ -6167,6 +6235,11 @@ PyInit__testcapi(void) PyModule_AddObject(m, "RecursingInfinitelyError", (PyObject *)&PyRecursingInfinitelyError_Type); + if (PyType_Ready(&BadGC2Type) < 0) + return NULL; + Py_INCREF(&BadGC2Type); + PyModule_AddObject(m, "BadGC2Type", (PyObject *)&BadGC2Type); + PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX)); PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN)); PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX));