bpo-29778: Ensure python3.dll is loaded from correct locations when P… · python/cpython@dcbaa1b (original) (raw)
`@@ -131,8 +131,6 @@ typedef struct {
`
131
131
`wchar_t machine_path; / from HKEY_LOCAL_MACHINE */
`
132
132
`wchar_t user_path; / from HKEY_CURRENT_USER */
`
133
133
``
134
``
`-
wchar_t *dll_path;
`
135
``
-
136
134
`const wchar_t *pythonpath_env;
`
137
135
`} PyCalculatePath;
`
138
136
``
`@@ -168,27 +166,37 @@ reduce(wchar_t *dir)
`
168
166
`static int
`
169
167
`change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
`
170
168
`{
`
171
``
`-
size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
`
172
``
`-
size_t i = src_len;
`
173
``
`-
if (i >= MAXPATHLEN+1) {
`
174
``
`-
Py_FatalError("buffer overflow in getpathp.c's reduce()");
`
175
``
`-
}
`
``
169
`+
if (src && src != dest) {
`
``
170
`+
size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
`
``
171
`+
size_t i = src_len;
`
``
172
`+
if (i >= MAXPATHLEN+1) {
`
``
173
`+
Py_FatalError("buffer overflow in getpathp.c's reduce()");
`
``
174
`+
}
`
176
175
``
177
``
`-
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
`
178
``
`-
--i;
`
``
176
`+
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
`
``
177
`+
--i;
`
179
178
``
180
``
`-
if (i == 0) {
`
181
``
`-
dest[0] = '\0';
`
182
``
`-
return -1;
`
183
``
`-
}
`
``
179
`+
if (i == 0) {
`
``
180
`+
dest[0] = '\0';
`
``
181
`+
return -1;
`
``
182
`+
}
`
``
183
+
``
184
`+
if (is_sep(src[i])) {
`
``
185
`+
i = src_len;
`
``
186
`+
}
`
184
187
``
185
``
`-
if (is_sep(src[i])) {
`
186
``
`-
i = src_len;
`
``
188
`+
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) {
`
``
189
`+
dest[0] = '\0';
`
``
190
`+
return -1;
`
``
191
`+
}
`
``
192
`+
} else {
`
``
193
`+
wchar_t *s = wcsrchr(dest, L'.');
`
``
194
`+
if (s) {
`
``
195
`+
s[0] = '\0';
`
``
196
`+
}
`
187
197
` }
`
188
198
``
189
``
`-
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
`
190
``
`-
wcscat_s(dest, MAXPATHLEN+1, ext))
`
191
``
`-
{
`
``
199
`+
if (wcscat_s(dest, MAXPATHLEN+1, ext)) {
`
192
200
`dest[0] = '\0';
`
193
201
`return -1;
`
194
202
` }
`
`@@ -297,6 +305,19 @@ search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *lan
`
297
305
`}
`
298
306
``
299
307
``
``
308
`+
static int
`
``
309
`+
get_dllpath(wchar_t *dllpath)
`
``
310
`+
{
`
``
311
`+
#ifdef Py_ENABLE_SHARED
`
``
312
`+
extern HANDLE PyWin_DLLhModule;
`
``
313
`+
if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) {
`
``
314
`+
return 0;
`
``
315
`+
}
`
``
316
`+
#endif
`
``
317
`+
return -1;
`
``
318
`+
}
`
``
319
+
``
320
+
300
321
`#ifdef Py_ENABLE_SHARED
`
301
322
``
302
323
`/* a string loaded from the DLL at startup.*/
`
`@@ -468,27 +489,6 @@ getpythonregpath(HKEY keyBase, int skipcore)
`
468
489
`#endif /* Py_ENABLE_SHARED */
`
469
490
``
470
491
``
471
``
`-
wchar_t*
`
472
``
`-
_Py_GetDLLPath(void)
`
473
``
`-
{
`
474
``
`-
wchar_t dll_path[MAXPATHLEN+1];
`
475
``
`-
memset(dll_path, 0, sizeof(dll_path));
`
476
``
-
477
``
`-
#ifdef Py_ENABLE_SHARED
`
478
``
`-
extern HANDLE PyWin_DLLhModule;
`
479
``
`-
if (PyWin_DLLhModule) {
`
480
``
`-
if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
`
481
``
`-
dll_path[0] = 0;
`
482
``
`-
}
`
483
``
`-
}
`
484
``
`-
#else
`
485
``
`-
dll_path[0] = 0;
`
486
``
`-
#endif
`
487
``
-
488
``
`-
return _PyMem_RawWcsdup(dll_path);
`
489
``
`-
}
`
490
``
-
491
``
-
492
492
`static PyStatus
`
493
493
`get_program_full_path(_PyPathConfig *pathconfig)
`
494
494
`{
`
`@@ -669,19 +669,17 @@ static int
`
669
669
`get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
`
670
670
`const _PyPathConfig *pathconfig)
`
671
671
`{
`
672
``
`-
if (calculate->dll_path[0]) {
`
673
``
`-
if (!change_ext(filename, calculate->dll_path, L"._pth") &&
`
674
``
`-
exists(filename))
`
675
``
`-
{
`
676
``
`-
return 1;
`
677
``
`-
}
`
``
672
`+
if (get_dllpath(filename) &&
`
``
673
`+
!change_ext(filename, filename, L"._pth") &&
`
``
674
`+
exists(filename))
`
``
675
`+
{
`
``
676
`+
return 1;
`
678
677
` }
`
679
``
`-
if (pathconfig->program_full_path[0]) {
`
680
``
`-
if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
`
681
``
`-
exists(filename))
`
682
``
`-
{
`
683
``
`-
return 1;
`
684
``
`-
}
`
``
678
`+
if (pathconfig->program_full_path[0] &&
`
``
679
`+
!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
`
``
680
`+
exists(filename))
`
``
681
`+
{
`
``
682
`+
return 1;
`
685
683
` }
`
686
684
`return 0;
`
687
685
`}
`
`@@ -994,9 +992,12 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
`
994
992
`wchar_t zip_path[MAXPATHLEN+1];
`
995
993
`memset(zip_path, 0, sizeof(zip_path));
`
996
994
``
997
``
`-
change_ext(zip_path,
`
998
``
`-
calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
`
999
``
`-
L".zip");
`
``
995
`+
if (get_dllpath(zip_path) || change_ext(zip_path, zip_path, L".zip"))
`
``
996
`+
{
`
``
997
`+
if (change_ext(zip_path, pathconfig->program_full_path, L".zip")) {
`
``
998
`+
zip_path[0] = L'\0';
`
``
999
`+
}
`
``
1000
`+
}
`
1000
1001
``
1001
1002
`calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
`
1002
1003
``
`@@ -1033,11 +1034,6 @@ calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
`
1033
1034
`calculate->home = pathconfig->home;
`
1034
1035
`calculate->path_env = _wgetenv(L"PATH");
`
1035
1036
``
1036
``
`-
calculate->dll_path = _Py_GetDLLPath();
`
1037
``
`-
if (calculate->dll_path == NULL) {
`
1038
``
`-
return _PyStatus_NO_MEMORY();
`
1039
``
`-
}
`
1040
``
-
1041
1037
`calculate->pythonpath_env = config->pythonpath_env;
`
1042
1038
``
1043
1039
`return _PyStatus_OK();
`
`@@ -1049,7 +1045,6 @@ calculate_free(PyCalculatePath *calculate)
`
1049
1045
`{
`
1050
1046
`PyMem_RawFree(calculate->machine_path);
`
1051
1047
`PyMem_RawFree(calculate->user_path);
`
1052
``
`-
PyMem_RawFree(calculate->dll_path);
`
1053
1048
`}
`
1054
1049
``
1055
1050
``
`@@ -1059,7 +1054,6 @@ calculate_free(PyCalculatePath *calculate)
`
1059
1054
``
1060
1055
` - PyConfig.pythonpath_env: PYTHONPATH environment variable
`
1061
1056
` - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
`
1062
``
`-
- DLL path: _Py_GetDLLPath()
`
1063
1057
` - PATH environment variable
`
1064
1058
` - PYVENV_LAUNCHER environment variable
`
1065
1059
` - GetModuleFileNameW(NULL): fully qualified path of the executable file of
`
`@@ -1113,33 +1107,35 @@ int
`
1113
1107
`_Py_CheckPython3(void)
`
1114
1108
`{
`
1115
1109
`wchar_t py3path[MAXPATHLEN+1];
`
1116
``
`-
wchar_t *s;
`
1117
1110
`if (python3_checked) {
`
1118
1111
`return hPython3 != NULL;
`
1119
1112
` }
`
1120
1113
`python3_checked = 1;
`
1121
1114
``
1122
1115
`/* If there is a python3.dll next to the python3y.dll,
`
1123
``
`-
assume this is a build tree; use that DLL */
`
1124
``
`-
if (_Py_dll_path != NULL) {
`
1125
``
`-
wcscpy(py3path, _Py_dll_path);
`
1126
``
`-
}
`
1127
``
`-
else {
`
1128
``
`-
wcscpy(py3path, L"");
`
1129
``
`-
}
`
1130
``
`-
s = wcsrchr(py3path, L'\');
`
1131
``
`-
if (!s) {
`
1132
``
`-
s = py3path;
`
``
1116
`+
use that DLL */
`
``
1117
`+
if (!get_dllpath(py3path)) {
`
``
1118
`+
reduce(py3path);
`
``
1119
`+
join(py3path, PY3_DLLNAME);
`
``
1120
`+
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
`
``
1121
`+
if (hPython3 != NULL) {
`
``
1122
`+
return 1;
`
``
1123
`+
}
`
1133
1124
` }
`
1134
``
`-
wcscpy(s, L"\python3.dll");
`
1135
``
`-
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
`
``
1125
+
``
1126
`+
/* If we can locate python3.dll in our application dir,
`
``
1127
`+
use that DLL */
`
``
1128
`+
hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
`
1136
1129
`if (hPython3 != NULL) {
`
1137
1130
`return 1;
`
1138
1131
` }
`
1139
1132
``
1140
``
`-
/* Check sys.prefix\DLLs\python3.dll */
`
``
1133
`+
/* For back-compat, also search {sys.prefix}\DLLs, though
`
``
1134
`+
that has not been a normal install layout for a while */
`
1141
1135
`wcscpy(py3path, Py_GetPrefix());
`
1142
``
`-
wcscat(py3path, L"\DLLs\python3.dll");
`
1143
``
`-
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
`
``
1136
`+
if (py3path[0]) {
`
``
1137
`+
join(py3path, L"DLLs\" PY3_DLLNAME);
`
``
1138
`+
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
`
``
1139
`+
}
`
1144
1140
`return hPython3 != NULL;
`
1145
1141
`}
`