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

``

`-

`

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

`}

`