Skip to content

Commit 8c08e86

Browse files
gh-90844: Allow virtual environments to correctly launch when they have spaces in the path (GH-94903)
(cherry picked from commit 4b4439d) Co-authored-by: Steve Dower <[email protected]>
1 parent b040617 commit 8c08e86

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Allow virtual environments to correctly launch when they have spaces in the
2+
path.

PC/launcher.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,27 +1926,35 @@ process(int argc, wchar_t ** argv)
19261926
if (!cch) {
19271927
error(0, L"Cannot determine memory for home path");
19281928
}
1929-
cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 1 + 1; /* include sep and null */
1929+
cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 4; /* include sep, null and quotes */
19301930
executable = (wchar_t *)malloc(cch * sizeof(wchar_t));
19311931
if (executable == NULL) {
19321932
error(RC_NO_MEMORY, L"A memory allocation failed");
19331933
}
1934-
cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, executable, cch);
1934+
/* start with a quote - we'll skip this ahead, but want it for the final string */
1935+
executable[0] = L'"';
1936+
cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, &executable[1], cch - 1);
19351937
if (!cch_actual) {
19361938
error(RC_BAD_VENV_CFG, L"Cannot decode home path in '%ls'",
19371939
venv_cfg_path);
19381940
}
1941+
cch_actual += 1; /* account for the first quote */
1942+
executable[cch_actual] = L'\0';
19391943
if (executable[cch_actual - 1] != L'\\') {
19401944
executable[cch_actual++] = L'\\';
19411945
executable[cch_actual] = L'\0';
19421946
}
1943-
if (wcscat_s(executable, cch, PYTHON_EXECUTABLE)) {
1947+
if (wcscat_s(&executable[1], cch - 1, PYTHON_EXECUTABLE)) {
19441948
error(RC_BAD_VENV_CFG, L"Cannot create executable path from '%ls'",
19451949
venv_cfg_path);
19461950
}
1947-
if (GetFileAttributesW(executable) == INVALID_FILE_ATTRIBUTES) {
1951+
/* there's no trailing quote, so we only have to skip one character for the test */
1952+
if (GetFileAttributesW(&executable[1]) == INVALID_FILE_ATTRIBUTES) {
19481953
error(RC_NO_PYTHON, L"No Python at '%ls'", executable);
19491954
}
1955+
/* now append the final quote */
1956+
wcscat_s(executable, cch, L"\"");
1957+
/* smuggle our original path through */
19501958
if (!SetEnvironmentVariableW(L"__PYVENV_LAUNCHER__", argv0)) {
19511959
error(0, L"Failed to set launcher environment");
19521960
}

0 commit comments

Comments
 (0)