mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-32457: Improves handling of denormalized executable path when launching Python (GH-5756) (#5818)
This commit is contained in:
parent
6eab93cfe5
commit
1d3c518c5e
3 changed files with 47 additions and 1 deletions
|
@ -489,6 +489,18 @@ class CmdLineTest(unittest.TestCase):
|
||||||
cwd=tmpdir)
|
cwd=tmpdir)
|
||||||
self.assertEqual(out.strip(), b"ok")
|
self.assertEqual(out.strip(), b"ok")
|
||||||
|
|
||||||
|
@unittest.skipUnless(sys.platform == 'win32',
|
||||||
|
'bpo-32457 only applies on Windows')
|
||||||
|
def test_argv0_normalization(self):
|
||||||
|
args = sys.executable, '-c', 'print(0)'
|
||||||
|
prefix, exe = os.path.split(sys.executable)
|
||||||
|
executable = prefix + '\\.\\.\\.\\' + exe
|
||||||
|
|
||||||
|
proc = subprocess.run(args, stdout=subprocess.PIPE,
|
||||||
|
executable=executable)
|
||||||
|
self.assertEqual(proc.returncode, 0, proc)
|
||||||
|
self.assertEqual(proc.stdout.strip(), b'0')
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test.support.run_unittest(CmdLineTest)
|
test.support.run_unittest(CmdLineTest)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Improves handling of denormalized executable path when launching Python.
|
|
@ -241,6 +241,36 @@ join(wchar_t *buffer, const wchar_t *stuff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _PathCchCanonicalizeEx_Initialized = 0;
|
||||||
|
typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cchPathOut,
|
||||||
|
PCWSTR pszPathIn, unsigned long dwFlags);
|
||||||
|
static PPathCchCanonicalizeEx _PathCchCanonicalizeEx;
|
||||||
|
|
||||||
|
static void canonicalize(wchar_t *buffer, const wchar_t *path)
|
||||||
|
{
|
||||||
|
if (_PathCchCanonicalizeEx_Initialized == 0) {
|
||||||
|
HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
|
||||||
|
if (pathapi) {
|
||||||
|
_PathCchCanonicalizeEx = (PPathCchCanonicalizeEx)GetProcAddress(pathapi, "PathCchCanonicalizeEx");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_PathCchCanonicalizeEx = NULL;
|
||||||
|
}
|
||||||
|
_PathCchCanonicalizeEx_Initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_PathCchCanonicalizeEx) {
|
||||||
|
if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) {
|
||||||
|
Py_FatalError("buffer overflow in getpathp.c's canonicalize()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!PathCanonicalizeW(buffer, path)) {
|
||||||
|
Py_FatalError("buffer overflow in getpathp.c's canonicalize()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* gotlandmark only called by search_for_prefix, which ensures
|
/* gotlandmark only called by search_for_prefix, which ensures
|
||||||
'prefix' is null terminated in bounds. join() ensures
|
'prefix' is null terminated in bounds. join() ensures
|
||||||
'landmark' can not overflow prefix if too long.
|
'landmark' can not overflow prefix if too long.
|
||||||
|
@ -431,6 +461,7 @@ static void
|
||||||
get_progpath(void)
|
get_progpath(void)
|
||||||
{
|
{
|
||||||
extern wchar_t *Py_GetProgramName(void);
|
extern wchar_t *Py_GetProgramName(void);
|
||||||
|
wchar_t modulepath[MAXPATHLEN];
|
||||||
wchar_t *path = _wgetenv(L"PATH");
|
wchar_t *path = _wgetenv(L"PATH");
|
||||||
wchar_t *prog = Py_GetProgramName();
|
wchar_t *prog = Py_GetProgramName();
|
||||||
|
|
||||||
|
@ -443,8 +474,10 @@ get_progpath(void)
|
||||||
#else
|
#else
|
||||||
dllpath[0] = 0;
|
dllpath[0] = 0;
|
||||||
#endif
|
#endif
|
||||||
if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN))
|
if (GetModuleFileNameW(NULL, modulepath, MAXPATHLEN)) {
|
||||||
|
canonicalize(progpath, modulepath);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (prog == NULL || *prog == '\0')
|
if (prog == NULL || *prog == '\0')
|
||||||
prog = L"python";
|
prog = L"python";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue