https://github.com/python/cpython/commit/812074e291d559824d496909a87fb5c26c37f60c
commit: 812074e291d559824d496909a87fb5c26c37f60c
branch: main
author: Sergey Miryanov <sergey.mirya...@gmail.com>
committer: encukou <encu...@gmail.com>
date: 2025-03-18T11:50:22+01:00
summary:

gh-131311: Consolidate reference handling in PyCStructUnionType_update_stginfo 
to fix memory leak (GH-131312)

files:
M Modules/_ctypes/stgdict.c

diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c
index 05239d85c44d2c..107716d85fed2d 100644
--- a/Modules/_ctypes/stgdict.c
+++ b/Modules/_ctypes/stgdict.c
@@ -217,13 +217,17 @@ MakeAnonFields(PyObject *type)
 int
 PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int 
isStruct)
 {
-    PyObject *tmp;
     Py_ssize_t ffi_ofs;
     int arrays_seen = 0;
 
     int retval = -1;
     // The following are NULL or hold strong references.
     // They're cleared on error.
+    PyObject *layout_func = NULL;
+    PyObject *kwnames = NULL;
+    PyObject* align = NULL;
+    PyObject* size = NULL;
+    PyObject *layout_fields_obj = NULL;
     PyObject *layout_fields = NULL;
     PyObject *layout = NULL;
     PyObject *format_spec_obj = NULL;
@@ -257,12 +261,11 @@ PyCStructUnionType_update_stginfo(PyObject *type, 
PyObject *fields, int isStruct
         goto error;
     }
 
-    PyObject *layout_func = PyImport_ImportModuleAttrString("ctypes._layout",
-                                                            "get_layout");
+    layout_func = PyImport_ImportModuleAttrString("ctypes._layout", 
"get_layout");
     if (!layout_func) {
         goto error;
     }
-    PyObject *kwnames = PyTuple_Pack(
+    kwnames = PyTuple_Pack(
         2,
         &_Py_ID(is_struct),
         &_Py_ID(base));
@@ -281,19 +284,19 @@ PyCStructUnionType_update_stginfo(PyObject *type, 
PyObject *fields, int isStruct
             baseinfo ? base : Py_None},
         2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
         kwnames);
-    Py_DECREF(kwnames);
-    Py_DECREF(layout_func);
+    Py_CLEAR(kwnames);
+    Py_CLEAR(layout_func);
     fields = NULL; // a borrowed reference we won't be using again
     if (!layout) {
         goto error;
     }
 
-    tmp = PyObject_GetAttr(layout, &_Py_ID(align));
-    if (!tmp) {
+    align = PyObject_GetAttr(layout, &_Py_ID(align));
+    if (!align) {
         goto error;
     }
-    Py_ssize_t total_align = PyLong_AsSsize_t(tmp);
-    Py_DECREF(tmp);
+    Py_ssize_t total_align = PyLong_AsSsize_t(align);
+    Py_CLEAR(align);
     if (total_align < 0) {
         if (!PyErr_Occurred()) {
             PyErr_SetString(PyExc_ValueError,
@@ -302,12 +305,12 @@ PyCStructUnionType_update_stginfo(PyObject *type, 
PyObject *fields, int isStruct
         goto error;
     }
 
-    tmp = PyObject_GetAttr(layout, &_Py_ID(size));
-    if (!tmp) {
+    size = PyObject_GetAttr(layout, &_Py_ID(size));
+    if (!size) {
         goto error;
     }
-    Py_ssize_t total_size = PyLong_AsSsize_t(tmp);
-    Py_DECREF(tmp);
+    Py_ssize_t total_size = PyLong_AsSsize_t(size);
+    Py_CLEAR(size);
     if (total_size < 0) {
         if (!PyErr_Occurred()) {
             PyErr_SetString(PyExc_ValueError,
@@ -338,15 +341,15 @@ PyCStructUnionType_update_stginfo(PyObject *type, 
PyObject *fields, int isStruct
     }
     memcpy(stginfo->format, format_spec, format_spec_size + 1);
 
-    PyObject *layout_fields_obj = PyObject_GetAttr(layout, &_Py_ID(fields));
+    layout_fields_obj = PyObject_GetAttr(layout, &_Py_ID(fields));
     if (!layout_fields_obj) {
         goto error;
     }
     layout_fields = PySequence_Tuple(layout_fields_obj);
-    Py_DECREF(layout_fields_obj);
     if (!layout_fields) {
         goto error;
     }
+    Py_CLEAR(layout_fields_obj);
     Py_CLEAR(layout);
 
     Py_ssize_t len = PyTuple_GET_SIZE(layout_fields);
@@ -664,6 +667,11 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject 
*fields, int isStruct
 
     retval = MakeAnonFields(type);
 error:
+    Py_XDECREF(layout_func);
+    Py_XDECREF(kwnames);
+    Py_XDECREF(align);
+    Py_XDECREF(size);
+    Py_XDECREF(layout_fields_obj);
     Py_XDECREF(layout_fields);
     Py_XDECREF(layout);
     Py_XDECREF(format_spec_obj);

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to