From cddd021a387424203cfb313dd3a11938ea73c25a Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 08:54:40 -0400 Subject: [PATCH 1/9] Fix reference leak in initialization of _tkinter --- Modules/_tkinter.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 1542d3af42f755..e9ac5d152b982b 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3419,8 +3419,9 @@ PyInit__tkinter(void) #endif Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); - if (PyModule_AddObjectRef(m, "TclError", Tkinter_TclError)) { + if (PyModule_AddObject(m, "TclError", Tkinter_TclError)) { Py_DECREF(m); + Py_DECREF(Tkinter_TclError); return NULL; } @@ -3470,20 +3471,23 @@ PyInit__tkinter(void) } Tkapp_Type = PyType_FromSpec(&Tkapp_Type_spec); - if (PyModule_AddObjectRef(m, "TkappType", Tkapp_Type)) { + if (PyModule_AddObject(m, "TkappType", Tkapp_Type)) { Py_DECREF(m); + Py_DECREF(Tkapp_Type); return NULL; } Tktt_Type = PyType_FromSpec(&Tktt_Type_spec); - if (PyModule_AddObjectRef(m, "TkttType", Tktt_Type)) { + if (PyModule_AddObject(m, "TkttType", Tktt_Type)) { Py_DECREF(m); + Py_DECREF(Tktt_Type); return NULL; } PyTclObject_Type = PyType_FromSpec(&PyTclObject_Type_spec); - if (PyModule_AddObjectRef(m, "Tcl_Obj", PyTclObject_Type)) { + if (PyModule_AddObject(m, "Tcl_Obj", PyTclObject_Type)) { Py_DECREF(m); + Py_DECREF(PyTclObject_Type); return NULL; } From a9eb482d3e5cb185081f627b09e3761ff575859e Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 09:01:40 -0400 Subject: [PATCH 2/9] Add NEWS entry. --- .../next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst diff --git a/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst b/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst new file mode 100644 index 00000000000000..45ec20bf5b70cb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst @@ -0,0 +1 @@ +Fixed reference leak in the initalization of :mod:`tkinter`. From 36c65afe57d6d4d25f15a946c13dd2c31ba424e5 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 11:31:57 -0400 Subject: [PATCH 3/9] Switch to `PyModule_AddObjectRef` --- Modules/_tkinter.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index e9ac5d152b982b..8927cf87a10cd0 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3419,7 +3419,7 @@ PyInit__tkinter(void) #endif Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); - if (PyModule_AddObject(m, "TclError", Tkinter_TclError)) { + if (PyModule_AddObjectRef(m, "TclError", Tkinter_TclError)) { Py_DECREF(m); Py_DECREF(Tkinter_TclError); return NULL; @@ -3471,25 +3471,25 @@ PyInit__tkinter(void) } Tkapp_Type = PyType_FromSpec(&Tkapp_Type_spec); - if (PyModule_AddObject(m, "TkappType", Tkapp_Type)) { + if (PyModule_AddObjectRef(m, "TkappType", Tkapp_Type)) { Py_DECREF(m); - Py_DECREF(Tkapp_Type); return NULL; } + Py_DECREF(Tkapp_Type); Tktt_Type = PyType_FromSpec(&Tktt_Type_spec); - if (PyModule_AddObject(m, "TkttType", Tktt_Type)) { + if (PyModule_AddObjectRef(m, "TkttType", Tktt_Type)) { Py_DECREF(m); - Py_DECREF(Tktt_Type); return NULL; } + Py_DECREF(Tktt_Type); PyTclObject_Type = PyType_FromSpec(&PyTclObject_Type_spec); - if (PyModule_AddObject(m, "Tcl_Obj", PyTclObject_Type)) { + if (PyModule_AddObjectRef(m, "Tcl_Obj", PyTclObject_Type)) { Py_DECREF(m); - Py_DECREF(PyTclObject_Type); return NULL; } + Py_DECREF(PyTclObject_Type); /* This helps the dynamic loader; in Unicode aware Tcl versions From cc291e4cdc3801f2f9592b4061570201c217cf4e Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 11:45:36 -0400 Subject: [PATCH 4/9] Switch to a module clear function. --- Modules/_tkinter.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 8927cf87a10cd0..bbc5510f1e53fb 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3389,6 +3389,14 @@ DisableEventHook(void) #endif } +static void +module_free(void *mod) +{ + Py_DECREF(Tkinter_TclError); + Py_DECREF(Tkapp_Type); + Py_DECREF(Tktt_Type); + Py_DECREF(PyTclObject_Type); +} static struct PyModuleDef _tkintermodule = { PyModuleDef_HEAD_INIT, @@ -3399,7 +3407,7 @@ static struct PyModuleDef _tkintermodule = { NULL, NULL, NULL, - NULL + module_free }; PyMODINIT_FUNC @@ -3421,7 +3429,6 @@ PyInit__tkinter(void) Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); if (PyModule_AddObjectRef(m, "TclError", Tkinter_TclError)) { Py_DECREF(m); - Py_DECREF(Tkinter_TclError); return NULL; } @@ -3475,22 +3482,18 @@ PyInit__tkinter(void) Py_DECREF(m); return NULL; } - Py_DECREF(Tkapp_Type); Tktt_Type = PyType_FromSpec(&Tktt_Type_spec); if (PyModule_AddObjectRef(m, "TkttType", Tktt_Type)) { Py_DECREF(m); return NULL; } - Py_DECREF(Tktt_Type); PyTclObject_Type = PyType_FromSpec(&PyTclObject_Type_spec); if (PyModule_AddObjectRef(m, "Tcl_Obj", PyTclObject_Type)) { Py_DECREF(m); return NULL; } - Py_DECREF(PyTclObject_Type); - /* This helps the dynamic loader; in Unicode aware Tcl versions it also helps Tcl find its encodings. */ From df9265f3f006fc728b1e3c49441df00355861d98 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 11:46:37 -0400 Subject: [PATCH 5/9] Add back missing newline. --- Modules/_tkinter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index bbc5510f1e53fb..65b18b14f2f647 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3489,6 +3489,7 @@ PyInit__tkinter(void) return NULL; } + PyTclObject_Type = PyType_FromSpec(&PyTclObject_Type_spec); if (PyModule_AddObjectRef(m, "Tcl_Obj", PyTclObject_Type)) { Py_DECREF(m); From 4f1f4e4932e959d0affdd72c99bb76f9162c6064 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 11:49:31 -0400 Subject: [PATCH 6/9] Fix formatting. --- Modules/_tkinter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 65b18b14f2f647..d1f73f5d6318eb 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3489,13 +3489,13 @@ PyInit__tkinter(void) return NULL; } - PyTclObject_Type = PyType_FromSpec(&PyTclObject_Type_spec); if (PyModule_AddObjectRef(m, "Tcl_Obj", PyTclObject_Type)) { Py_DECREF(m); return NULL; } + /* This helps the dynamic loader; in Unicode aware Tcl versions it also helps Tcl find its encodings. */ uexe = PySys_GetObject("executable"); // borrowed reference From a77abbafc59404ef57290ccce0ca0258a976010f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 30 Aug 2024 12:05:46 -0400 Subject: [PATCH 7/9] Switch to `Py_CLEAR` --- Modules/_tkinter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index d1f73f5d6318eb..65b82c6f730ae1 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3392,10 +3392,10 @@ DisableEventHook(void) static void module_free(void *mod) { - Py_DECREF(Tkinter_TclError); - Py_DECREF(Tkapp_Type); - Py_DECREF(Tktt_Type); - Py_DECREF(PyTclObject_Type); + Py_CLEAR(Tkinter_TclError); + Py_CLEAR(Tkapp_Type); + Py_CLEAR(Tktt_Type); + Py_CLEAR(PyTclObject_Type); } static struct PyModuleDef _tkintermodule = { From f35f2a0c9ae97889787e4f6c63225e0d5a12509c Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 2 Sep 2024 20:26:59 -0400 Subject: [PATCH 8/9] Update Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst Co-authored-by: Victor Stinner --- .../next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst b/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst index 45ec20bf5b70cb..ea504d3532dc44 100644 --- a/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst +++ b/Misc/NEWS.d/next/Library/2024-08-30-09-01-35.gh-issue-123504.lJ9_BB.rst @@ -1 +1 @@ -Fixed reference leak in the initalization of :mod:`tkinter`. +Fixed reference leak in the finalization of :mod:`tkinter`. From fc34562e0de245b958420d2c787dec20ef963b47 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 3 Sep 2024 16:10:17 -0400 Subject: [PATCH 9/9] Use dot notation for module initializer. --- Modules/_tkinter.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 65b82c6f730ae1..e1e81082d9ec47 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3389,25 +3389,28 @@ DisableEventHook(void) #endif } -static void -module_free(void *mod) +static int +module_clear(PyObject *mod) { Py_CLEAR(Tkinter_TclError); Py_CLEAR(Tkapp_Type); Py_CLEAR(Tktt_Type); Py_CLEAR(PyTclObject_Type); + return 0; +} + +static void +module_free(void *mod) +{ + module_clear((PyObject *)mod); } static struct PyModuleDef _tkintermodule = { PyModuleDef_HEAD_INIT, - "_tkinter", - NULL, - -1, - moduleMethods, - NULL, - NULL, - NULL, - module_free + .m_name = "_tkinter", + .m_methods = moduleMethods, + .m_clear = module_clear, + .m_free = module_free }; PyMODINIT_FUNC