From c7cd37bbc38d8586503f1c717441dfa53fd4d09c Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 21 Mar 2026 16:31:12 +0800 Subject: [PATCH 1/4] Fix memory leak in `SET_ITEM` macro in `initconfig.c` when expression evaluation fails --- ...-03-21-16-24-10.gh-issue-146244.Oztf9i.rst | 2 ++ Python/initconfig.c | 19 +++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-21-16-24-10.gh-issue-146244.Oztf9i.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-21-16-24-10.gh-issue-146244.Oztf9i.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-21-16-24-10.gh-issue-146244.Oztf9i.rst new file mode 100644 index 00000000000000..dfb4410caff626 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-21-16-24-10.gh-issue-146244.Oztf9i.rst @@ -0,0 +1,2 @@ +Fix memory leak in ``SET_ITEM`` macro in ``initconfig.c`` when expression +evaluation fails diff --git a/Python/initconfig.c b/Python/initconfig.c index caf42f5247c2f2..d566586d5b7a70 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -508,17 +508,16 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS } #define SET_ITEM(KEY, EXPR) \ - do { \ - obj = (EXPR); \ - if (obj == NULL) { \ - return NULL; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ + do { \ + obj = (EXPR); \ + if (obj == NULL) \ + goto fail; \ + if (PyDict_SetItemString(dict, (KEY), obj) < 0) { \ Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) + goto fail; \ + } \ + Py_DECREF(obj); \ + } while (0) #define SET_ITEM_INT(VAR) \ SET_ITEM(#VAR, PyLong_FromLong(VAR)) #define FROM_STRING(STR) \ From f0168d48c14d59d525551600da867a14b480555f Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 21 Mar 2026 16:31:41 +0800 Subject: [PATCH 2/4] fix --- Python/initconfig.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index d566586d5b7a70..df3b5b503e9cb6 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -512,11 +512,10 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS obj = (EXPR); \ if (obj == NULL) \ goto fail; \ - if (PyDict_SetItemString(dict, (KEY), obj) < 0) { \ - Py_DECREF(obj); \ - goto fail; \ - } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ Py_DECREF(obj); \ + if (res < 0) \ + goto fail; \ } while (0) #define SET_ITEM_INT(VAR) \ SET_ITEM(#VAR, PyLong_FromLong(VAR)) From fed0c314d4f67cc25dff3f0a7293c7ff9c6923c8 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 21 Mar 2026 16:43:23 +0800 Subject: [PATCH 3/4] fix --- Python/initconfig.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index df3b5b503e9cb6..01a89b95c29a5b 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -508,15 +508,15 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS } #define SET_ITEM(KEY, EXPR) \ - do { \ - obj = (EXPR); \ - if (obj == NULL) \ - goto fail; \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) \ - goto fail; \ - } while (0) + do { \ + obj = (EXPR); \ + if (obj == NULL) \ + goto fail; \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) \ + goto fail; \ + } while (0) #define SET_ITEM_INT(VAR) \ SET_ITEM(#VAR, PyLong_FromLong(VAR)) #define FROM_STRING(STR) \ From 312b124ca3d1e180ea7e75ed2f3d599a366e97ce Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 21 Mar 2026 16:45:31 +0800 Subject: [PATCH 4/4] fix --- Python/initconfig.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index 01a89b95c29a5b..8dc9602ff13df7 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -510,12 +510,14 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS #define SET_ITEM(KEY, EXPR) \ do { \ obj = (EXPR); \ - if (obj == NULL) \ + if (obj == NULL) { \ goto fail; \ + } \ int res = PyDict_SetItemString(dict, (KEY), obj); \ Py_DECREF(obj); \ - if (res < 0) \ + if (res < 0) { \ goto fail; \ + } \ } while (0) #define SET_ITEM_INT(VAR) \ SET_ITEM(#VAR, PyLong_FromLong(VAR))