mirror of
https://github.com/python/cpython.git
synced 2025-11-24 20:30:18 +00:00
[3.14] gh-138756: Fix memory leak in PyInitConfig_Free() (GH-138759) (#138785)
gh-138756: Fix memory leak in PyInitConfig_Free() (GH-138759)
Clear also memory of PyConfig members.
(cherry picked from commit 96dee64c73)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
6ed9be1a55
commit
0accda7468
1 changed files with 51 additions and 9 deletions
|
|
@ -239,9 +239,11 @@ static const PyConfigSpec PYPRECONFIG_SPEC[] = {
|
|||
|
||||
|
||||
// Forward declarations
|
||||
static PyObject*
|
||||
config_get(const PyConfig *config, const PyConfigSpec *spec,
|
||||
int use_sys);
|
||||
static PyObject* config_get(const PyConfig *config, const PyConfigSpec *spec,
|
||||
int use_sys);
|
||||
static void initconfig_free_wstr(wchar_t *member);
|
||||
static void initconfig_free_wstr_list(PyWideStringList *list);
|
||||
static void initconfig_free_config(const PyConfig *config);
|
||||
|
||||
|
||||
/* --- Command line options --------------------------------------- */
|
||||
|
|
@ -3725,6 +3727,8 @@ PyInitConfig_Free(PyInitConfig *config)
|
|||
if (config == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
initconfig_free_config(&config->config);
|
||||
free(config->err_msg);
|
||||
free(config);
|
||||
}
|
||||
|
|
@ -4093,13 +4097,51 @@ PyInitConfig_SetStr(PyInitConfig *config, const char *name, const char* value)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
initconfig_free_wstr(wchar_t *member)
|
||||
{
|
||||
if (member) {
|
||||
free(member);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initconfig_free_wstr_list(PyWideStringList *list)
|
||||
{
|
||||
for (Py_ssize_t i = 0; i < list->length; i++) {
|
||||
free(list->items[i]);
|
||||
}
|
||||
free(list->items);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initconfig_free_config(const PyConfig *config)
|
||||
{
|
||||
const PyConfigSpec *spec = PYCONFIG_SPEC;
|
||||
for (; spec->name != NULL; spec++) {
|
||||
void *member = config_get_spec_member(config, spec);
|
||||
if (spec->type == PyConfig_MEMBER_WSTR
|
||||
|| spec->type == PyConfig_MEMBER_WSTR_OPT)
|
||||
{
|
||||
wchar_t *wstr = *(wchar_t **)member;
|
||||
initconfig_free_wstr(wstr);
|
||||
}
|
||||
else if (spec->type == PyConfig_MEMBER_WSTR_LIST) {
|
||||
initconfig_free_wstr_list(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_PyWideStringList_FromUTF8(PyInitConfig *config, PyWideStringList *list,
|
||||
Py_ssize_t length, char * const *items)
|
||||
initconfig_set_str_list(PyInitConfig *config, PyWideStringList *list,
|
||||
Py_ssize_t length, char * const *items)
|
||||
{
|
||||
PyWideStringList wlist = _PyWideStringList_INIT;
|
||||
size_t size = sizeof(wchar_t*) * length;
|
||||
wlist.items = (wchar_t **)PyMem_RawMalloc(size);
|
||||
wlist.items = (wchar_t **)malloc(size);
|
||||
if (wlist.items == NULL) {
|
||||
config->status = _PyStatus_NO_MEMORY();
|
||||
return -1;
|
||||
|
|
@ -4108,14 +4150,14 @@ _PyWideStringList_FromUTF8(PyInitConfig *config, PyWideStringList *list,
|
|||
for (Py_ssize_t i = 0; i < length; i++) {
|
||||
wchar_t *arg = utf8_to_wstr(config, items[i]);
|
||||
if (arg == NULL) {
|
||||
_PyWideStringList_Clear(&wlist);
|
||||
initconfig_free_wstr_list(&wlist);
|
||||
return -1;
|
||||
}
|
||||
wlist.items[i] = arg;
|
||||
wlist.length++;
|
||||
}
|
||||
|
||||
_PyWideStringList_Clear(list);
|
||||
initconfig_free_wstr_list(list);
|
||||
*list = wlist;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4136,7 +4178,7 @@ PyInitConfig_SetStrList(PyInitConfig *config, const char *name,
|
|||
return -1;
|
||||
}
|
||||
PyWideStringList *list = raw_member;
|
||||
if (_PyWideStringList_FromUTF8(config, list, length, items) < 0) {
|
||||
if (initconfig_set_str_list(config, list, length, items) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue