From 73b91f58d0bfa387880ab94ccb20afd08f634c53 Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Fri, 25 Nov 2022 15:10:05 +0000 Subject: [PATCH 1/8] Support arbitrary number of loaded modules on Windows Changed the TKinter module loading function for Windows to support the rare (but possible) case of having more than 1024 modules loaded. This is an adaptation of the same fix that was added to Matplotlib in [PR #22445](https://github.com/matplotlib/matplotlib/pull/22445). --- src/Tk/tkImaging.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 16b9a2eddb5..58ca23a5699 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -310,7 +310,7 @@ load_tkinter_funcs(void) { * Return 0 for success, non-zero for failure. */ - HMODULE hMods[1024]; + HMODULE* hMods = NULL; HANDLE hProcess; DWORD cbNeeded; unsigned int i; @@ -327,33 +327,45 @@ load_tkinter_funcs(void) { /* Returns pseudo-handle that does not need to be closed */ hProcess = GetCurrentProcess(); + /* Allocate module handlers array */ + if (!EnumProcessModules(hProcess, NULL, 0, &cbNeeded)) { + PyErr_SetFromWindowsErr(0); + return 1; + } + if (!(hMods = static_cast(malloc(cbNeeded)))) { + PyErr_NoMemory(); + return 1; + } + /* Iterate through modules in this process looking for Tcl / Tk names */ - if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { + if (EnumProcessModules(hProcess, hMods, cbNeeded, &cbNeeded)) { for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { if (!found_tcl) { found_tcl = get_tcl(hMods[i]); if (found_tcl == -1) { - return 1; + goto exit; } } if (!found_tk) { found_tk = get_tk(hMods[i]); if (found_tk == -1) { - return 1; + goto exit; } } if (found_tcl && found_tk) { - return 0; + goto exit; } } } - if (found_tcl == 0) { +exit: + free(hMods); + if (found_tcl != 1) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tcl routines"); - } else { + } else if (found_tk != 1) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines"); } - return 1; + return int((found_tcl != 1) && (found_tk != 1)); } #else /* not Windows */ From 40d9732a40cc577c3cd914dc3d22f0ccdeec9a2e Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Fri, 25 Nov 2022 15:57:07 +0000 Subject: [PATCH 2/8] Fix cast syntax --- src/Tk/tkImaging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 58ca23a5699..68afb988a4c 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -332,7 +332,7 @@ load_tkinter_funcs(void) { PyErr_SetFromWindowsErr(0); return 1; } - if (!(hMods = static_cast(malloc(cbNeeded)))) { + if (!(hMods = (HMODULE*) malloc(cbNeeded))) { PyErr_NoMemory(); return 1; } From 80d7fa9004e35001a843a64f4accd0cb51e75813 Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Fri, 25 Nov 2022 16:09:01 +0000 Subject: [PATCH 3/8] Fix another bad cast syntax --- src/Tk/tkImaging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 68afb988a4c..9b4b1d8f50c 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -365,7 +365,7 @@ load_tkinter_funcs(void) { } else if (found_tk != 1) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines"); } - return int((found_tcl != 1) && (found_tk != 1)); + return (int) ((found_tcl != 1) && (found_tk != 1)); } #else /* not Windows */ From 4a36d9d761790d88c98e08dd273dbc7abb0c71b2 Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Fri, 25 Nov 2022 22:27:18 +0000 Subject: [PATCH 4/8] Avoid using PyErr_SetFromWindowsErr on Cygwin --- src/Tk/tkImaging.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 9b4b1d8f50c..e16f33eb085 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -329,7 +329,11 @@ load_tkinter_funcs(void) { /* Allocate module handlers array */ if (!EnumProcessModules(hProcess, NULL, 0, &cbNeeded)) { +#if defined(__CYGWIN__) + PyErr_SetString(PyExc_OSError, "Call to EnumProcessModules failed"); +#else PyErr_SetFromWindowsErr(0); +#endif return 1; } if (!(hMods = (HMODULE*) malloc(cbNeeded))) { From 406a8478cd73c5c166783e9d3583b2249e3b7068 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 26 Nov 2022 17:41:06 +1100 Subject: [PATCH 5/8] Use break instead of goto --- src/Tk/tkImaging.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index e16f33eb085..506bb7008f7 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -347,22 +347,21 @@ load_tkinter_funcs(void) { if (!found_tcl) { found_tcl = get_tcl(hMods[i]); if (found_tcl == -1) { - goto exit; + break; } } if (!found_tk) { found_tk = get_tk(hMods[i]); if (found_tk == -1) { - goto exit; + break; } } if (found_tcl && found_tk) { - goto exit; + break; } } } -exit: free(hMods); if (found_tcl != 1) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tcl routines"); From e945ab382aee9d043525c19b53b67d6e47adf2fe Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Thu, 5 Jan 2023 00:04:50 +0000 Subject: [PATCH 6/8] Fix tcl/tk loading error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ondrej Baranovič --- src/Tk/tkImaging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 506bb7008f7..6ad3aaba18f 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -368,7 +368,7 @@ load_tkinter_funcs(void) { } else if (found_tk != 1) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines"); } - return (int) ((found_tcl != 1) && (found_tk != 1)); + return (int) ((found_tcl != 1) || (found_tk != 1)); } #else /* not Windows */ From da39e4e38e866e715eccf29feb23a444ab23f60b Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Thu, 5 Jan 2023 00:05:36 +0000 Subject: [PATCH 7/8] Fix tcl/tk loading error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ondrej Baranovič --- src/Tk/tkImaging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 6ad3aaba18f..8225756ba38 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -365,7 +365,7 @@ load_tkinter_funcs(void) { free(hMods); if (found_tcl != 1) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tcl routines"); - } else if (found_tk != 1) { + } else if (found_tk == 0) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines"); } return (int) ((found_tcl != 1) || (found_tk != 1)); From 2cc40cc7f4a7d51b29c66c0da4d785a5d5920c3c Mon Sep 17 00:00:00 2001 From: Javier Dehesa Date: Thu, 5 Jan 2023 00:05:54 +0000 Subject: [PATCH 8/8] Fix tcl/tk loading error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ondrej Baranovič --- src/Tk/tkImaging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index 8225756ba38..ad503baec61 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -363,7 +363,7 @@ load_tkinter_funcs(void) { } free(hMods); - if (found_tcl != 1) { + if (found_tcl == 0) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tcl routines"); } else if (found_tk == 0) { PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines");