mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-131311: Consolidate reference handling in PyCStructUnionType_update_stginfo to fix memory leak (GH-131312)
This commit is contained in:
parent
3453b5c1d6
commit
812074e291
1 changed files with 24 additions and 16 deletions
|
@ -217,13 +217,17 @@ MakeAnonFields(PyObject *type)
|
||||||
int
|
int
|
||||||
PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct)
|
PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct)
|
||||||
{
|
{
|
||||||
PyObject *tmp;
|
|
||||||
Py_ssize_t ffi_ofs;
|
Py_ssize_t ffi_ofs;
|
||||||
int arrays_seen = 0;
|
int arrays_seen = 0;
|
||||||
|
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
// The following are NULL or hold strong references.
|
// The following are NULL or hold strong references.
|
||||||
// They're cleared on error.
|
// 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_fields = NULL;
|
||||||
PyObject *layout = NULL;
|
PyObject *layout = NULL;
|
||||||
PyObject *format_spec_obj = NULL;
|
PyObject *format_spec_obj = NULL;
|
||||||
|
@ -257,12 +261,11 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *layout_func = PyImport_ImportModuleAttrString("ctypes._layout",
|
layout_func = PyImport_ImportModuleAttrString("ctypes._layout", "get_layout");
|
||||||
"get_layout");
|
|
||||||
if (!layout_func) {
|
if (!layout_func) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
PyObject *kwnames = PyTuple_Pack(
|
kwnames = PyTuple_Pack(
|
||||||
2,
|
2,
|
||||||
&_Py_ID(is_struct),
|
&_Py_ID(is_struct),
|
||||||
&_Py_ID(base));
|
&_Py_ID(base));
|
||||||
|
@ -281,19 +284,19 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
|
||||||
baseinfo ? base : Py_None},
|
baseinfo ? base : Py_None},
|
||||||
2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||||
kwnames);
|
kwnames);
|
||||||
Py_DECREF(kwnames);
|
Py_CLEAR(kwnames);
|
||||||
Py_DECREF(layout_func);
|
Py_CLEAR(layout_func);
|
||||||
fields = NULL; // a borrowed reference we won't be using again
|
fields = NULL; // a borrowed reference we won't be using again
|
||||||
if (!layout) {
|
if (!layout) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = PyObject_GetAttr(layout, &_Py_ID(align));
|
align = PyObject_GetAttr(layout, &_Py_ID(align));
|
||||||
if (!tmp) {
|
if (!align) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
Py_ssize_t total_align = PyLong_AsSsize_t(tmp);
|
Py_ssize_t total_align = PyLong_AsSsize_t(align);
|
||||||
Py_DECREF(tmp);
|
Py_CLEAR(align);
|
||||||
if (total_align < 0) {
|
if (total_align < 0) {
|
||||||
if (!PyErr_Occurred()) {
|
if (!PyErr_Occurred()) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
@ -302,12 +305,12 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = PyObject_GetAttr(layout, &_Py_ID(size));
|
size = PyObject_GetAttr(layout, &_Py_ID(size));
|
||||||
if (!tmp) {
|
if (!size) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
Py_ssize_t total_size = PyLong_AsSsize_t(tmp);
|
Py_ssize_t total_size = PyLong_AsSsize_t(size);
|
||||||
Py_DECREF(tmp);
|
Py_CLEAR(size);
|
||||||
if (total_size < 0) {
|
if (total_size < 0) {
|
||||||
if (!PyErr_Occurred()) {
|
if (!PyErr_Occurred()) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
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);
|
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) {
|
if (!layout_fields_obj) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
layout_fields = PySequence_Tuple(layout_fields_obj);
|
layout_fields = PySequence_Tuple(layout_fields_obj);
|
||||||
Py_DECREF(layout_fields_obj);
|
|
||||||
if (!layout_fields) {
|
if (!layout_fields) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
Py_CLEAR(layout_fields_obj);
|
||||||
Py_CLEAR(layout);
|
Py_CLEAR(layout);
|
||||||
|
|
||||||
Py_ssize_t len = PyTuple_GET_SIZE(layout_fields);
|
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);
|
retval = MakeAnonFields(type);
|
||||||
error:
|
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_fields);
|
||||||
Py_XDECREF(layout);
|
Py_XDECREF(layout);
|
||||||
Py_XDECREF(format_spec_obj);
|
Py_XDECREF(format_spec_obj);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue