]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-90844: Allow virtual environments to correctly launch when they have spaces in...
authorSteve Dower <steve.dower@python.org>
Sat, 16 Jul 2022 16:38:36 +0000 (17:38 +0100)
committerGitHub <noreply@github.com>
Sat, 16 Jul 2022 16:38:36 +0000 (17:38 +0100)
Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst [new file with mode: 0644]
PC/launcher.c

diff --git a/Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst b/Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst
new file mode 100644 (file)
index 0000000..8d9e850
--- /dev/null
@@ -0,0 +1,2 @@
+Allow virtual environments to correctly launch when they have spaces in the
+path.
index de7abeb4e86abdcc153e4a5ef2263291962311b7..da566a180168c5d80104e68b3595f140c4ba989f 100644 (file)
@@ -1926,27 +1926,35 @@ process(int argc, wchar_t ** argv)
         if (!cch) {
             error(0, L"Cannot determine memory for home path");
         }
-        cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 1 + 1; /* include sep and null */
+        cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 4; /* include sep, null and quotes */
         executable = (wchar_t *)malloc(cch * sizeof(wchar_t));
         if (executable == NULL) {
             error(RC_NO_MEMORY, L"A memory allocation failed");
         }
-        cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, executable, cch);
+        /* start with a quote - we'll skip this ahead, but want it for the final string */
+        executable[0] = L'"';
+        cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, &executable[1], cch - 1);
         if (!cch_actual) {
             error(RC_BAD_VENV_CFG, L"Cannot decode home path in '%ls'",
                   venv_cfg_path);
         }
+        cch_actual += 1; /* account for the first quote */
+        executable[cch_actual] = L'\0';
         if (executable[cch_actual - 1] != L'\\') {
             executable[cch_actual++] = L'\\';
             executable[cch_actual] = L'\0';
         }
-        if (wcscat_s(executable, cch, PYTHON_EXECUTABLE)) {
+        if (wcscat_s(&executable[1], cch - 1, PYTHON_EXECUTABLE)) {
             error(RC_BAD_VENV_CFG, L"Cannot create executable path from '%ls'",
                   venv_cfg_path);
         }
-        if (GetFileAttributesW(executable) == INVALID_FILE_ATTRIBUTES) {
+        /* there's no trailing quote, so we only have to skip one character for the test */
+        if (GetFileAttributesW(&executable[1]) == INVALID_FILE_ATTRIBUTES) {
             error(RC_NO_PYTHON, L"No Python at '%ls'", executable);
         }
+        /* now append the final quote */
+        wcscat_s(executable, cch, L"\"");
+        /* smuggle our original path through */
         if (!SetEnvironmentVariableW(L"__PYVENV_LAUNCHER__", argv0)) {
             error(0, L"Failed to set launcher environment");
         }