Unverified Kaydet (Commit) 1d3c518c authored tarafından Steve Dower's avatar Steve Dower Kaydeden (comit) GitHub

bpo-32457: Improves handling of denormalized executable path when launching…

bpo-32457: Improves handling of denormalized executable path when launching Python (GH-5756) (#5818)
üst 6eab93cf
...@@ -489,6 +489,18 @@ class CmdLineTest(unittest.TestCase): ...@@ -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)
......
Improves handling of denormalized executable path when launching Python.
...@@ -241,6 +241,36 @@ join(wchar_t *buffer, const wchar_t *stuff) ...@@ -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 ...@@ -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) ...@@ -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";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment