bpo-28441: Ensure `.exe` suffix in `sys.executable` on MinGW and Cygw… · python/cpython@e5897b6
@@ -296,6 +296,41 @@ absolutize(wchar_t *path)
296296}
297297298298299+#if defined(__CYGWIN__) || defined(__MINGW32__)
300+/* add_exe_suffix requires that progpath be allocated at least
301+ MAXPATHLEN + 1 bytes.
302+*/
303+304+#ifndef EXE_SUFFIX
305+#define EXE_SUFFIX L".exe"
306+#endif
307+308+static void
309+add_exe_suffix(wchar_t *progpath)
310+{
311+/* Check for already have an executable suffix */
312+size_t n = wcslen(progpath);
313+size_t s = wcslen(EXE_SUFFIX);
314+if (wcsncasecmp(EXE_SUFFIX, progpath+n-s, s) != 0) {
315+if (n + s > MAXPATHLEN) {
316+Py_FatalError("progpath overflow in getpath.c's add_exe_suffix()");
317+ }
318+/* Save original path for revert */
319+wchar_t orig[MAXPATHLEN+1];
320+wcsncpy(orig, progpath, MAXPATHLEN);
321+322+wcsncpy(progpath+n, EXE_SUFFIX, s);
323+progpath[n+s] = '\0';
324+325+if (!isxfile(progpath)) {
326+/* Path that added suffix is invalid */
327+wcsncpy(progpath, orig, MAXPATHLEN);
328+ }
329+ }
330+}
331+#endif
332+333+299334/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
300335 bytes long.
301336*/
@@ -605,6 +640,16 @@ calculate_program_full_path(const _PyCoreConfig *core_config,
605640if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
606641absolutize(program_full_path);
607642 }
643+#if defined(__CYGWIN__) || defined(__MINGW32__)
644+/* For these platforms it is necessary to ensure that the .exe suffix
645+ * is appended to the filename, otherwise there is potential for
646+ * sys.executable to return the name of a directory under the same
647+ * path (bpo-28441).
648+ */
649+if (program_full_path[0] != '\0') {
650+add_exe_suffix(program_full_path);
651+ }
652+#endif
608653609654config->program_full_path = _PyMem_RawWcsdup(program_full_path);
610655if (config->program_full_path == NULL) {