From 9c4fb92e126000650a8efb4d27c4e3d1af82f71e Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Mon, 24 Mar 2025 17:42:10 +0500 Subject: [PATCH] gh-131311: Fix additional memory leaks in ctypes (GH-131429) * Visit keep in StructParam_traverse * Decref swapped in PyCSimpleType_init * Decref ob in make_funcptrtype_dict * Check Pointer_item result while constructing result list in Pointer_subscript * Fix align and size naming in PyCStructUnionType_update_stginfo - as discussed in previous PR --- Modules/_ctypes/_ctypes.c | 10 +++++++++- Modules/_ctypes/stgdict.c | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index cc06759f2d0d..ef4d98ea56ff 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -410,9 +410,11 @@ typedef struct { #define _StructParamObject_CAST(op) ((StructParamObject *)(op)) static int -StructParam_traverse(PyObject *self, visitproc visit, void *arg) +StructParam_traverse(PyObject *myself, visitproc visit, void *arg) { + StructParamObject *self = _StructParamObject_CAST(myself); Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->keep); return 0; } @@ -2378,6 +2380,7 @@ PyCSimpleType_init(PyObject *self, PyObject *args, PyObject *kwds) } StgInfo *sw_info; if (PyStgInfo_FromType(st, swapped, &sw_info) < 0) { + Py_DECREF(swapped); return -1; } assert(sw_info); @@ -2674,6 +2677,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo) if (ob) { StgInfo *info; if (PyStgInfo_FromType(st, ob, &info) < 0) { + Py_DECREF(ob); return -1; } if (ob != Py_None && !info && !PyCallable_Check(ob)) { @@ -5650,6 +5654,10 @@ Pointer_subscript(PyObject *myself, PyObject *item) for (cur = start, i = 0; i < len; cur += step, i++) { PyObject *v = Pointer_item(myself, cur); + if (!v) { + Py_DECREF(np); + return NULL; + } PyList_SET_ITEM(np, i, v); } return np; diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 107716d85fed..4779d362d6a2 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -225,8 +225,8 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct // They're cleared on error. PyObject *layout_func = NULL; PyObject *kwnames = NULL; - PyObject* align = NULL; - PyObject* size = NULL; + PyObject *align_obj = NULL; + PyObject *size_obj = NULL; PyObject *layout_fields_obj = NULL; PyObject *layout_fields = NULL; PyObject *layout = NULL; @@ -291,12 +291,12 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct goto error; } - align = PyObject_GetAttr(layout, &_Py_ID(align)); - if (!align) { + align_obj = PyObject_GetAttr(layout, &_Py_ID(align)); + if (!align_obj) { goto error; } - Py_ssize_t total_align = PyLong_AsSsize_t(align); - Py_CLEAR(align); + Py_ssize_t total_align = PyLong_AsSsize_t(align_obj); + Py_CLEAR(align_obj); if (total_align < 0) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, @@ -305,12 +305,12 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct goto error; } - size = PyObject_GetAttr(layout, &_Py_ID(size)); - if (!size) { + size_obj = PyObject_GetAttr(layout, &_Py_ID(size)); + if (!size_obj) { goto error; } - Py_ssize_t total_size = PyLong_AsSsize_t(size); - Py_CLEAR(size); + Py_ssize_t total_size = PyLong_AsSsize_t(size_obj); + Py_CLEAR(size_obj); if (total_size < 0) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, @@ -669,8 +669,8 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct error: Py_XDECREF(layout_func); Py_XDECREF(kwnames); - Py_XDECREF(align); - Py_XDECREF(size); + Py_XDECREF(align_obj); + Py_XDECREF(size_obj); Py_XDECREF(layout_fields_obj); Py_XDECREF(layout_fields); Py_XDECREF(layout); -- 2.47.3