bpo-29778: Ensure python3.dll is loaded from correct locations when P… · python/cpython@aa7f775 (original) (raw)
`@@ -130,8 +130,6 @@ typedef struct {
`
130
130
`wchar_t machine_path; / from HKEY_LOCAL_MACHINE */
`
131
131
`wchar_t user_path; / from HKEY_CURRENT_USER */
`
132
132
``
133
``
`-
wchar_t *dll_path;
`
134
``
-
135
133
`const wchar_t *pythonpath_env;
`
136
134
`} PyCalculatePath;
`
137
135
``
`@@ -167,27 +165,37 @@ reduce(wchar_t *dir)
`
167
165
`static int
`
168
166
`change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
`
169
167
`{
`
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
``
`-
}
`
``
168
`+
if (src && src != dest) {
`
``
169
`+
size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
`
``
170
`+
size_t i = src_len;
`
``
171
`+
if (i >= MAXPATHLEN+1) {
`
``
172
`+
Py_FatalError("buffer overflow in getpathp.c's reduce()");
`
``
173
`+
}
`
175
174
``
176
``
`-
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
`
177
``
`-
--i;
`
``
175
`+
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
`
``
176
`+
--i;
`
178
177
``
179
``
`-
if (i == 0) {
`
180
``
`-
dest[0] = '\0';
`
181
``
`-
return -1;
`
182
``
`-
}
`
``
178
`+
if (i == 0) {
`
``
179
`+
dest[0] = '\0';
`
``
180
`+
return -1;
`
``
181
`+
}
`
``
182
+
``
183
`+
if (is_sep(src[i])) {
`
``
184
`+
i = src_len;
`
``
185
`+
}
`
183
186
``
184
``
`-
if (is_sep(src[i])) {
`
185
``
`-
i = src_len;
`
``
187
`+
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) {
`
``
188
`+
dest[0] = '\0';
`
``
189
`+
return -1;
`
``
190
`+
}
`
``
191
`+
} else {
`
``
192
`+
wchar_t *s = wcsrchr(dest, L'.');
`
``
193
`+
if (s) {
`
``
194
`+
s[0] = '\0';
`
``
195
`+
}
`
186
196
` }
`
187
197
``
188
``
`-
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
`
189
``
`-
wcscat_s(dest, MAXPATHLEN+1, ext))
`
190
``
`-
{
`
``
198
`+
if (wcscat_s(dest, MAXPATHLEN+1, ext)) {
`
191
199
`dest[0] = '\0';
`
192
200
`return -1;
`
193
201
` }
`
`@@ -344,6 +352,19 @@ search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *lan
`
344
352
`}
`
345
353
``
346
354
``
``
355
`+
static int
`
``
356
`+
get_dllpath(wchar_t *dllpath)
`
``
357
`+
{
`
``
358
`+
#ifdef Py_ENABLE_SHARED
`
``
359
`+
extern HANDLE PyWin_DLLhModule;
`
``
360
`+
if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) {
`
``
361
`+
return 0;
`
``
362
`+
}
`
``
363
`+
#endif
`
``
364
`+
return -1;
`
``
365
`+
}
`
``
366
+
``
367
+
347
368
`#ifdef Py_ENABLE_SHARED
`
348
369
``
349
370
`/* a string loaded from the DLL at startup.*/
`
`@@ -516,27 +537,6 @@ getpythonregpath(HKEY keyBase, int skipcore)
`
516
537
`#endif /* Py_ENABLE_SHARED */
`
517
538
``
518
539
``
519
``
`-
wchar_t*
`
520
``
`-
_Py_GetDLLPath(void)
`
521
``
`-
{
`
522
``
`-
wchar_t dll_path[MAXPATHLEN+1];
`
523
``
`-
memset(dll_path, 0, sizeof(dll_path));
`
524
``
-
525
``
`-
#ifdef Py_ENABLE_SHARED
`
526
``
`-
extern HANDLE PyWin_DLLhModule;
`
527
``
`-
if (PyWin_DLLhModule) {
`
528
``
`-
if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
`
529
``
`-
dll_path[0] = 0;
`
530
``
`-
}
`
531
``
`-
}
`
532
``
`-
#else
`
533
``
`-
dll_path[0] = 0;
`
534
``
`-
#endif
`
535
``
-
536
``
`-
return _PyMem_RawWcsdup(dll_path);
`
537
``
`-
}
`
538
``
-
539
``
-
540
540
`static PyStatus
`
541
541
`get_program_full_path(_PyPathConfig *pathconfig)
`
542
542
`{
`
`@@ -717,19 +717,17 @@ static int
`
717
717
`get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
`
718
718
`const _PyPathConfig *pathconfig)
`
719
719
`{
`
720
``
`-
if (calculate->dll_path[0]) {
`
721
``
`-
if (!change_ext(filename, calculate->dll_path, L"._pth") &&
`
722
``
`-
exists(filename))
`
723
``
`-
{
`
724
``
`-
return 1;
`
725
``
`-
}
`
``
720
`+
if (get_dllpath(filename) &&
`
``
721
`+
!change_ext(filename, filename, L"._pth") &&
`
``
722
`+
exists(filename))
`
``
723
`+
{
`
``
724
`+
return 1;
`
726
725
` }
`
727
``
`-
if (pathconfig->program_full_path[0]) {
`
728
``
`-
if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
`
729
``
`-
exists(filename))
`
730
``
`-
{
`
731
``
`-
return 1;
`
732
``
`-
}
`
``
726
`+
if (pathconfig->program_full_path[0] &&
`
``
727
`+
!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
`
``
728
`+
exists(filename))
`
``
729
`+
{
`
``
730
`+
return 1;
`
733
731
` }
`
734
732
`return 0;
`
735
733
`}
`
`@@ -1029,9 +1027,12 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
`
1029
1027
`wchar_t zip_path[MAXPATHLEN+1];
`
1030
1028
`memset(zip_path, 0, sizeof(zip_path));
`
1031
1029
``
1032
``
`-
change_ext(zip_path,
`
1033
``
`-
calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
`
1034
``
`-
L".zip");
`
``
1030
`+
if (get_dllpath(zip_path) || change_ext(zip_path, zip_path, L".zip"))
`
``
1031
`+
{
`
``
1032
`+
if (change_ext(zip_path, pathconfig->program_full_path, L".zip")) {
`
``
1033
`+
zip_path[0] = L'\0';
`
``
1034
`+
}
`
``
1035
`+
}
`
1035
1036
``
1036
1037
`calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
`
1037
1038
``
`@@ -1068,11 +1069,6 @@ calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
`
1068
1069
`calculate->home = pathconfig->home;
`
1069
1070
`calculate->path_env = _wgetenv(L"PATH");
`
1070
1071
``
1071
``
`-
calculate->dll_path = _Py_GetDLLPath();
`
1072
``
`-
if (calculate->dll_path == NULL) {
`
1073
``
`-
return _PyStatus_NO_MEMORY();
`
1074
``
`-
}
`
1075
``
-
1076
1072
`calculate->pythonpath_env = config->pythonpath_env;
`
1077
1073
``
1078
1074
`return _PyStatus_OK();
`
`@@ -1084,7 +1080,6 @@ calculate_free(PyCalculatePath *calculate)
`
1084
1080
`{
`
1085
1081
`PyMem_RawFree(calculate->machine_path);
`
1086
1082
`PyMem_RawFree(calculate->user_path);
`
1087
``
`-
PyMem_RawFree(calculate->dll_path);
`
1088
1083
`}
`
1089
1084
``
1090
1085
``
`@@ -1094,7 +1089,6 @@ calculate_free(PyCalculatePath *calculate)
`
1094
1089
``
1095
1090
` - PyConfig.pythonpath_env: PYTHONPATH environment variable
`
1096
1091
` - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
`
1097
``
`-
- DLL path: _Py_GetDLLPath()
`
1098
1092
` - PATH environment variable
`
1099
1093
` - PYVENV_LAUNCHER environment variable
`
1100
1094
` - GetModuleFileNameW(NULL): fully qualified path of the executable file of
`
`@@ -1148,33 +1142,35 @@ int
`
1148
1142
`_Py_CheckPython3(void)
`
1149
1143
`{
`
1150
1144
`wchar_t py3path[MAXPATHLEN+1];
`
1151
``
`-
wchar_t *s;
`
1152
1145
`if (python3_checked) {
`
1153
1146
`return hPython3 != NULL;
`
1154
1147
` }
`
1155
1148
`python3_checked = 1;
`
1156
1149
``
1157
1150
`/* If there is a python3.dll next to the python3y.dll,
`
1158
``
`-
assume this is a build tree; use that DLL */
`
1159
``
`-
if (_Py_dll_path != NULL) {
`
1160
``
`-
wcscpy(py3path, _Py_dll_path);
`
1161
``
`-
}
`
1162
``
`-
else {
`
1163
``
`-
wcscpy(py3path, L"");
`
1164
``
`-
}
`
1165
``
`-
s = wcsrchr(py3path, L'\');
`
1166
``
`-
if (!s) {
`
1167
``
`-
s = py3path;
`
``
1151
`+
use that DLL */
`
``
1152
`+
if (!get_dllpath(py3path)) {
`
``
1153
`+
reduce(py3path);
`
``
1154
`+
join(py3path, PY3_DLLNAME);
`
``
1155
`+
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
`
``
1156
`+
if (hPython3 != NULL) {
`
``
1157
`+
return 1;
`
``
1158
`+
}
`
1168
1159
` }
`
1169
``
`-
wcscpy(s, L"\python3.dll");
`
1170
``
`-
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
`
``
1160
+
``
1161
`+
/* If we can locate python3.dll in our application dir,
`
``
1162
`+
use that DLL */
`
``
1163
`+
hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
`
1171
1164
`if (hPython3 != NULL) {
`
1172
1165
`return 1;
`
1173
1166
` }
`
1174
1167
``
1175
``
`-
/* Check sys.prefix\DLLs\python3.dll */
`
``
1168
`+
/* For back-compat, also search {sys.prefix}\DLLs, though
`
``
1169
`+
that has not been a normal install layout for a while */
`
1176
1170
`wcscpy(py3path, Py_GetPrefix());
`
1177
``
`-
wcscat(py3path, L"\DLLs\python3.dll");
`
1178
``
`-
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
`
``
1171
`+
if (py3path[0]) {
`
``
1172
`+
join(py3path, L"DLLs\" PY3_DLLNAME);
`
``
1173
`+
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
`
``
1174
`+
}
`
1179
1175
`return hPython3 != NULL;
`
1180
1176
`}
`