bpo-29778: Ensure python3.dll is loaded from correct locations when Python is embedded (GH-21297)
Also enables using debug build of `python3_d.dll` Reference: CVE-2020-15523
This commit is contained in:
parent
deb016224c
commit
dcbaa1b49c
|
@ -32,7 +32,7 @@ API_ISOLATED = 3
|
||||||
def debug_build(program):
|
def debug_build(program):
|
||||||
program = os.path.basename(program)
|
program = os.path.basename(program)
|
||||||
name = os.path.splitext(program)[0]
|
name = os.path.splitext(program)[0]
|
||||||
return name.endswith("_d")
|
return name.casefold().endswith("_d".casefold())
|
||||||
|
|
||||||
|
|
||||||
def remove_python_envvars():
|
def remove_python_envvars():
|
||||||
|
@ -568,7 +568,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
if expected['stdio_errors'] is self.GET_DEFAULT_CONFIG:
|
if expected['stdio_errors'] is self.GET_DEFAULT_CONFIG:
|
||||||
expected['stdio_errors'] = 'surrogateescape'
|
expected['stdio_errors'] = 'surrogateescape'
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if MS_WINDOWS:
|
||||||
default_executable = self.test_exe
|
default_executable = self.test_exe
|
||||||
elif expected['program_name'] is not self.GET_DEFAULT_CONFIG:
|
elif expected['program_name'] is not self.GET_DEFAULT_CONFIG:
|
||||||
default_executable = os.path.abspath(expected['program_name'])
|
default_executable = os.path.abspath(expected['program_name'])
|
||||||
|
@ -603,7 +603,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
pre_config = dict(configs['pre_config'])
|
pre_config = dict(configs['pre_config'])
|
||||||
for key, value in list(expected.items()):
|
for key, value in list(expected.items()):
|
||||||
if value is self.IGNORE_CONFIG:
|
if value is self.IGNORE_CONFIG:
|
||||||
del pre_config[key]
|
pre_config.pop(key, None)
|
||||||
del expected[key]
|
del expected[key]
|
||||||
self.assertEqual(pre_config, expected)
|
self.assertEqual(pre_config, expected)
|
||||||
|
|
||||||
|
@ -611,7 +611,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
config = dict(configs['config'])
|
config = dict(configs['config'])
|
||||||
for key, value in list(expected.items()):
|
for key, value in list(expected.items()):
|
||||||
if value is self.IGNORE_CONFIG:
|
if value is self.IGNORE_CONFIG:
|
||||||
del config[key]
|
config.pop(key, None)
|
||||||
del expected[key]
|
del expected[key]
|
||||||
self.assertEqual(config, expected)
|
self.assertEqual(config, expected)
|
||||||
|
|
||||||
|
@ -686,6 +686,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
self.check_pre_config(configs, expected_preconfig)
|
self.check_pre_config(configs, expected_preconfig)
|
||||||
self.check_config(configs, expected_config)
|
self.check_config(configs, expected_config)
|
||||||
self.check_global_config(configs)
|
self.check_global_config(configs)
|
||||||
|
return configs
|
||||||
|
|
||||||
def test_init_default_config(self):
|
def test_init_default_config(self):
|
||||||
self.check_all_configs("test_init_initialize_config", api=API_COMPAT)
|
self.check_all_configs("test_init_initialize_config", api=API_COMPAT)
|
||||||
|
@ -1064,6 +1065,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
}
|
}
|
||||||
self.default_program_name(config)
|
self.default_program_name(config)
|
||||||
env = {'TESTPATH': os.path.pathsep.join(paths)}
|
env = {'TESTPATH': os.path.pathsep.join(paths)}
|
||||||
|
|
||||||
self.check_all_configs("test_init_setpath", config,
|
self.check_all_configs("test_init_setpath", config,
|
||||||
api=API_COMPAT, env=env,
|
api=API_COMPAT, env=env,
|
||||||
ignore_stderr=True)
|
ignore_stderr=True)
|
||||||
|
@ -1121,12 +1123,18 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
# Copy pythonXY.dll (or pythonXY_d.dll)
|
# Copy pythonXY.dll (or pythonXY_d.dll)
|
||||||
ver = sys.version_info
|
ver = sys.version_info
|
||||||
dll = f'python{ver.major}{ver.minor}'
|
dll = f'python{ver.major}{ver.minor}'
|
||||||
|
dll3 = f'python{ver.major}'
|
||||||
if debug_build(sys.executable):
|
if debug_build(sys.executable):
|
||||||
dll += '_d'
|
dll += '_d'
|
||||||
|
dll3 += '_d'
|
||||||
dll += '.dll'
|
dll += '.dll'
|
||||||
|
dll3 += '.dll'
|
||||||
dll = os.path.join(os.path.dirname(self.test_exe), dll)
|
dll = os.path.join(os.path.dirname(self.test_exe), dll)
|
||||||
|
dll3 = os.path.join(os.path.dirname(self.test_exe), dll3)
|
||||||
dll_copy = os.path.join(tmpdir, os.path.basename(dll))
|
dll_copy = os.path.join(tmpdir, os.path.basename(dll))
|
||||||
|
dll3_copy = os.path.join(tmpdir, os.path.basename(dll3))
|
||||||
shutil.copyfile(dll, dll_copy)
|
shutil.copyfile(dll, dll_copy)
|
||||||
|
shutil.copyfile(dll3, dll3_copy)
|
||||||
|
|
||||||
# Copy Python program
|
# Copy Python program
|
||||||
exec_copy = os.path.join(tmpdir, os.path.basename(self.test_exe))
|
exec_copy = os.path.join(tmpdir, os.path.basename(self.test_exe))
|
||||||
|
@ -1254,9 +1262,18 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
config['base_prefix'] = pyvenv_home
|
config['base_prefix'] = pyvenv_home
|
||||||
config['prefix'] = pyvenv_home
|
config['prefix'] = pyvenv_home
|
||||||
env = self.copy_paths_by_env(config)
|
env = self.copy_paths_by_env(config)
|
||||||
self.check_all_configs("test_init_compat_config", config,
|
actual = self.check_all_configs("test_init_compat_config", config,
|
||||||
api=API_COMPAT, env=env,
|
api=API_COMPAT, env=env,
|
||||||
ignore_stderr=True, cwd=tmpdir)
|
ignore_stderr=True, cwd=tmpdir)
|
||||||
|
if MS_WINDOWS:
|
||||||
|
self.assertEqual(
|
||||||
|
actual['windows']['python3_dll'],
|
||||||
|
os.path.join(
|
||||||
|
tmpdir,
|
||||||
|
os.path.basename(self.EXPECTED_CONFIG['windows']['python3_dll'])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_global_pathconfig(self):
|
def test_global_pathconfig(self):
|
||||||
# Test C API functions getting the path configuration:
|
# Test C API functions getting the path configuration:
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Ensure :file:`python3.dll` is loaded from correct locations when Python is
|
||||||
|
embedded (CVE-2020-15523).
|
|
@ -18,10 +18,53 @@
|
||||||
#include "pycore_gc.h" // PyGC_Head
|
#include "pycore_gc.h" // PyGC_Head
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
_add_windows_config(PyObject *configs)
|
||||||
|
{
|
||||||
|
HMODULE hPython3;
|
||||||
|
wchar_t py3path[MAX_PATH];
|
||||||
|
PyObject *dict = PyDict_New();
|
||||||
|
PyObject *obj = NULL;
|
||||||
|
if (!dict) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hPython3 = GetModuleHandleW(PY3_DLLNAME);
|
||||||
|
if (hPython3 && GetModuleFileNameW(hPython3, py3path, MAX_PATH)) {
|
||||||
|
obj = PyUnicode_FromWideChar(py3path, -1);
|
||||||
|
} else {
|
||||||
|
obj = Py_None;
|
||||||
|
Py_INCREF(obj);
|
||||||
|
}
|
||||||
|
if (obj &&
|
||||||
|
!PyDict_SetItemString(dict, "python3_dll", obj) &&
|
||||||
|
!PyDict_SetItemString(configs, "windows", dict)) {
|
||||||
|
Py_DECREF(obj);
|
||||||
|
Py_DECREF(dict);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Py_DECREF(obj);
|
||||||
|
Py_DECREF(dict);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
get_configs(PyObject *self, PyObject *Py_UNUSED(args))
|
get_configs(PyObject *self, PyObject *Py_UNUSED(args))
|
||||||
{
|
{
|
||||||
return _Py_GetConfigsAsDict();
|
PyObject *dict = _Py_GetConfigsAsDict();
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
if (dict) {
|
||||||
|
if (_add_windows_config(dict) < 0) {
|
||||||
|
Py_CLEAR(dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
156
PC/getpathp.c
156
PC/getpathp.c
|
@ -131,8 +131,6 @@ typedef struct {
|
||||||
wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
|
wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
|
||||||
wchar_t *user_path; /* from HKEY_CURRENT_USER */
|
wchar_t *user_path; /* from HKEY_CURRENT_USER */
|
||||||
|
|
||||||
wchar_t *dll_path;
|
|
||||||
|
|
||||||
const wchar_t *pythonpath_env;
|
const wchar_t *pythonpath_env;
|
||||||
} PyCalculatePath;
|
} PyCalculatePath;
|
||||||
|
|
||||||
|
@ -168,27 +166,37 @@ reduce(wchar_t *dir)
|
||||||
static int
|
static int
|
||||||
change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
|
change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
|
||||||
{
|
{
|
||||||
size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
|
if (src && src != dest) {
|
||||||
size_t i = src_len;
|
size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
|
||||||
if (i >= MAXPATHLEN+1) {
|
size_t i = src_len;
|
||||||
Py_FatalError("buffer overflow in getpathp.c's reduce()");
|
if (i >= MAXPATHLEN+1) {
|
||||||
|
Py_FatalError("buffer overflow in getpathp.c's reduce()");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
|
||||||
|
--i;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
dest[0] = '\0';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_sep(src[i])) {
|
||||||
|
i = src_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) {
|
||||||
|
dest[0] = '\0';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wchar_t *s = wcsrchr(dest, L'.');
|
||||||
|
if (s) {
|
||||||
|
s[0] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i > 0 && src[i] != '.' && !is_sep(src[i]))
|
if (wcscat_s(dest, MAXPATHLEN+1, ext)) {
|
||||||
--i;
|
|
||||||
|
|
||||||
if (i == 0) {
|
|
||||||
dest[0] = '\0';
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_sep(src[i])) {
|
|
||||||
i = src_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
|
|
||||||
wcscat_s(dest, MAXPATHLEN+1, ext))
|
|
||||||
{
|
|
||||||
dest[0] = '\0';
|
dest[0] = '\0';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +305,19 @@ search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *lan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_dllpath(wchar_t *dllpath)
|
||||||
|
{
|
||||||
|
#ifdef Py_ENABLE_SHARED
|
||||||
|
extern HANDLE PyWin_DLLhModule;
|
||||||
|
if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef Py_ENABLE_SHARED
|
#ifdef Py_ENABLE_SHARED
|
||||||
|
|
||||||
/* a string loaded from the DLL at startup.*/
|
/* a string loaded from the DLL at startup.*/
|
||||||
|
@ -468,27 +489,6 @@ done:
|
||||||
#endif /* Py_ENABLE_SHARED */
|
#endif /* Py_ENABLE_SHARED */
|
||||||
|
|
||||||
|
|
||||||
wchar_t*
|
|
||||||
_Py_GetDLLPath(void)
|
|
||||||
{
|
|
||||||
wchar_t dll_path[MAXPATHLEN+1];
|
|
||||||
memset(dll_path, 0, sizeof(dll_path));
|
|
||||||
|
|
||||||
#ifdef Py_ENABLE_SHARED
|
|
||||||
extern HANDLE PyWin_DLLhModule;
|
|
||||||
if (PyWin_DLLhModule) {
|
|
||||||
if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
|
|
||||||
dll_path[0] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
dll_path[0] = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return _PyMem_RawWcsdup(dll_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
get_program_full_path(_PyPathConfig *pathconfig)
|
get_program_full_path(_PyPathConfig *pathconfig)
|
||||||
{
|
{
|
||||||
|
@ -669,19 +669,17 @@ static int
|
||||||
get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
|
get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
|
||||||
const _PyPathConfig *pathconfig)
|
const _PyPathConfig *pathconfig)
|
||||||
{
|
{
|
||||||
if (calculate->dll_path[0]) {
|
if (get_dllpath(filename) &&
|
||||||
if (!change_ext(filename, calculate->dll_path, L"._pth") &&
|
!change_ext(filename, filename, L"._pth") &&
|
||||||
exists(filename))
|
exists(filename))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (pathconfig->program_full_path[0]) {
|
if (pathconfig->program_full_path[0] &&
|
||||||
if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
|
!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
|
||||||
exists(filename))
|
exists(filename))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -994,9 +992,12 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
||||||
wchar_t zip_path[MAXPATHLEN+1];
|
wchar_t zip_path[MAXPATHLEN+1];
|
||||||
memset(zip_path, 0, sizeof(zip_path));
|
memset(zip_path, 0, sizeof(zip_path));
|
||||||
|
|
||||||
change_ext(zip_path,
|
if (get_dllpath(zip_path) || change_ext(zip_path, zip_path, L".zip"))
|
||||||
calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
|
{
|
||||||
L".zip");
|
if (change_ext(zip_path, pathconfig->program_full_path, L".zip")) {
|
||||||
|
zip_path[0] = L'\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
|
calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
|
||||||
|
|
||||||
|
@ -1033,11 +1034,6 @@ calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
||||||
calculate->home = pathconfig->home;
|
calculate->home = pathconfig->home;
|
||||||
calculate->path_env = _wgetenv(L"PATH");
|
calculate->path_env = _wgetenv(L"PATH");
|
||||||
|
|
||||||
calculate->dll_path = _Py_GetDLLPath();
|
|
||||||
if (calculate->dll_path == NULL) {
|
|
||||||
return _PyStatus_NO_MEMORY();
|
|
||||||
}
|
|
||||||
|
|
||||||
calculate->pythonpath_env = config->pythonpath_env;
|
calculate->pythonpath_env = config->pythonpath_env;
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
|
@ -1049,7 +1045,6 @@ calculate_free(PyCalculatePath *calculate)
|
||||||
{
|
{
|
||||||
PyMem_RawFree(calculate->machine_path);
|
PyMem_RawFree(calculate->machine_path);
|
||||||
PyMem_RawFree(calculate->user_path);
|
PyMem_RawFree(calculate->user_path);
|
||||||
PyMem_RawFree(calculate->dll_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1059,7 +1054,6 @@ calculate_free(PyCalculatePath *calculate)
|
||||||
|
|
||||||
- PyConfig.pythonpath_env: PYTHONPATH environment variable
|
- PyConfig.pythonpath_env: PYTHONPATH environment variable
|
||||||
- _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
|
- _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
|
||||||
- DLL path: _Py_GetDLLPath()
|
|
||||||
- PATH environment variable
|
- PATH environment variable
|
||||||
- __PYVENV_LAUNCHER__ environment variable
|
- __PYVENV_LAUNCHER__ environment variable
|
||||||
- GetModuleFileNameW(NULL): fully qualified path of the executable file of
|
- GetModuleFileNameW(NULL): fully qualified path of the executable file of
|
||||||
|
@ -1113,33 +1107,35 @@ int
|
||||||
_Py_CheckPython3(void)
|
_Py_CheckPython3(void)
|
||||||
{
|
{
|
||||||
wchar_t py3path[MAXPATHLEN+1];
|
wchar_t py3path[MAXPATHLEN+1];
|
||||||
wchar_t *s;
|
|
||||||
if (python3_checked) {
|
if (python3_checked) {
|
||||||
return hPython3 != NULL;
|
return hPython3 != NULL;
|
||||||
}
|
}
|
||||||
python3_checked = 1;
|
python3_checked = 1;
|
||||||
|
|
||||||
/* If there is a python3.dll next to the python3y.dll,
|
/* If there is a python3.dll next to the python3y.dll,
|
||||||
assume this is a build tree; use that DLL */
|
use that DLL */
|
||||||
if (_Py_dll_path != NULL) {
|
if (!get_dllpath(py3path)) {
|
||||||
wcscpy(py3path, _Py_dll_path);
|
reduce(py3path);
|
||||||
|
join(py3path, PY3_DLLNAME);
|
||||||
|
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||||
|
if (hPython3 != NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
wcscpy(py3path, L"");
|
/* If we can locate python3.dll in our application dir,
|
||||||
}
|
use that DLL */
|
||||||
s = wcsrchr(py3path, L'\\');
|
hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
|
||||||
if (!s) {
|
|
||||||
s = py3path;
|
|
||||||
}
|
|
||||||
wcscpy(s, L"\\python3.dll");
|
|
||||||
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
|
||||||
if (hPython3 != NULL) {
|
if (hPython3 != NULL) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check sys.prefix\DLLs\python3.dll */
|
/* For back-compat, also search {sys.prefix}\DLLs, though
|
||||||
|
that has not been a normal install layout for a while */
|
||||||
wcscpy(py3path, Py_GetPrefix());
|
wcscpy(py3path, Py_GetPrefix());
|
||||||
wcscat(py3path, L"\\DLLs\\python3.dll");
|
if (py3path[0]) {
|
||||||
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
join(py3path, L"DLLs\\" PY3_DLLNAME);
|
||||||
|
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||||
|
}
|
||||||
return hPython3 != NULL;
|
return hPython3 != NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,12 @@
|
||||||
<_PlatformPreprocessorDefinition>_WIN32;</_PlatformPreprocessorDefinition>
|
<_PlatformPreprocessorDefinition>_WIN32;</_PlatformPreprocessorDefinition>
|
||||||
<_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;_M_X64;</_PlatformPreprocessorDefinition>
|
<_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;_M_X64;</_PlatformPreprocessorDefinition>
|
||||||
<_PydPreprocessorDefinition Condition="$(TargetExt) == '.pyd'">Py_BUILD_CORE_MODULE;</_PydPreprocessorDefinition>
|
<_PydPreprocessorDefinition Condition="$(TargetExt) == '.pyd'">Py_BUILD_CORE_MODULE;</_PydPreprocessorDefinition>
|
||||||
|
<_Py3NamePreprocessorDefinition>PY3_DLLNAME=L"$(Py3DllName)";</_Py3NamePreprocessorDefinition>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
|
|
@ -203,6 +203,8 @@
|
||||||
|
|
||||||
<!-- The name of the resulting pythonXY.dll (without the extension) -->
|
<!-- The name of the resulting pythonXY.dll (without the extension) -->
|
||||||
<PyDllName>python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt)</PyDllName>
|
<PyDllName>python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt)</PyDllName>
|
||||||
|
<!-- The name of the resulting pythonX.dll (without the extension) -->
|
||||||
|
<Py3DllName>python3$(PyDebugExt)</Py3DllName>
|
||||||
|
|
||||||
<!-- The version and platform tag to include in .pyd filenames -->
|
<!-- The version and platform tag to include in .pyd filenames -->
|
||||||
<PydTag Condition="$(ArchName) == 'win32'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win32</PydTag>
|
<PydTag Condition="$(ArchName) == 'win32'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win32</PydTag>
|
||||||
|
|
|
@ -168,9 +168,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
|
||||||
char funcname[258], *import_python;
|
char funcname[258], *import_python;
|
||||||
const wchar_t *wpathname;
|
const wchar_t *wpathname;
|
||||||
|
|
||||||
#ifndef _DEBUG
|
|
||||||
_Py_CheckPython3();
|
_Py_CheckPython3();
|
||||||
#endif
|
|
||||||
|
|
||||||
wpathname = _PyUnicode_AsUnicode(pathname);
|
wpathname = _PyUnicode_AsUnicode(pathname);
|
||||||
if (wpathname == NULL)
|
if (wpathname == NULL)
|
||||||
|
|
|
@ -17,9 +17,6 @@ extern "C" {
|
||||||
|
|
||||||
|
|
||||||
_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
|
_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
wchar_t *_Py_dll_path = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -107,10 +104,6 @@ _PyPathConfig_ClearGlobal(void)
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
pathconfig_clear(&_Py_path_config);
|
pathconfig_clear(&_Py_path_config);
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
PyMem_RawFree(_Py_dll_path);
|
|
||||||
_Py_dll_path = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
}
|
}
|
||||||
|
@ -147,31 +140,6 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
/* Initialize _Py_dll_path on Windows. Do nothing on other platforms. */
|
|
||||||
static PyStatus
|
|
||||||
_PyPathConfig_InitDLLPath(void)
|
|
||||||
{
|
|
||||||
if (_Py_dll_path != NULL) {
|
|
||||||
/* Already set: nothing to do */
|
|
||||||
return _PyStatus_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyMemAllocatorEx old_alloc;
|
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
|
||||||
|
|
||||||
_Py_dll_path = _Py_GetDLLPath();
|
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
|
||||||
|
|
||||||
if (_Py_dll_path == NULL) {
|
|
||||||
return _PyStatus_NO_MEMORY();
|
|
||||||
}
|
|
||||||
return _PyStatus_OK();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
|
pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
|
||||||
{
|
{
|
||||||
|
@ -222,13 +190,6 @@ done:
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyConfig_WritePathConfig(const PyConfig *config)
|
_PyConfig_WritePathConfig(const PyConfig *config)
|
||||||
{
|
{
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
PyStatus status = _PyPathConfig_InitDLLPath();
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return pathconfig_set_from_config(&_Py_path_config, config);
|
return pathconfig_set_from_config(&_Py_path_config, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,13 +416,6 @@ pathconfig_global_init(void)
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
status = _PyPathConfig_InitDLLPath();
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
Py_ExitStatusException(status);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_Py_path_config.module_search_path == NULL) {
|
if (_Py_path_config.module_search_path == NULL) {
|
||||||
status = pathconfig_global_read(&_Py_path_config);
|
status = pathconfig_global_read(&_Py_path_config);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
|
Loading…
Reference in New Issue