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

``

`-

`

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

`}

`