diff options
author | Steve Dower <steve.dower@microsoft.com> | 2016-09-18 00:25:42 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2016-09-18 00:25:42 (GMT) |
commit | 1ec262be80f9439296918c20b55a5a6686af5347 (patch) | |
tree | 42f5b521ed55c302a02bfbabb6d52282b280eba5 /Python | |
parent | 1c75c18ed2242a9e274eea11815c67fe8a67df40 (diff) | |
download | cpython-1ec262be80f9439296918c20b55a5a6686af5347.zip cpython-1ec262be80f9439296918c20b55a5a6686af5347.tar.gz cpython-1ec262be80f9439296918c20b55a5a6686af5347.tar.bz2 |
Issue #27932: Prevent memory leak in win32_ver().
Diffstat (limited to 'Python')
-rw-r--r-- | Python/sysmodule.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 8d7e05a..f688349 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -825,6 +825,7 @@ static PyStructSequence_Field windows_version_fields[] = { {"service_pack_minor", "Service Pack minor version number"}, {"suite_mask", "Bit mask identifying available product suites"}, {"product_type", "System product type"}, + {"_platform_version", "Diagnostic version number"}, {0} }; @@ -849,6 +850,12 @@ sys_getwindowsversion(PyObject *self) PyObject *version; int pos = 0; OSVERSIONINFOEX ver; + DWORD realMajor, realMinor, realBuild; + HANDLE hKernel32; + wchar_t kernel32_path[MAX_PATH]; + LPVOID verblock; + DWORD verblock_size; + ver.dwOSVersionInfoSize = sizeof(ver); if (!GetVersionEx((OSVERSIONINFO*) &ver)) return PyErr_SetFromWindowsErr(0); @@ -867,10 +874,40 @@ sys_getwindowsversion(PyObject *self) PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); + realMajor = ver.dwMajorVersion; + realMinor = ver.dwMinorVersion; + realBuild = ver.dwBuildNumber; + + // GetVersion will lie if we are running in a compatibility mode. + // We need to read the version info from a system file resource + // to accurately identify the OS version. If we fail for any reason, + // just return whatever GetVersion said. + hKernel32 = GetModuleHandleW(L"kernel32.dll"); + if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && + (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) && + (verblock = PyMem_RawMalloc(verblock_size))) { + VS_FIXEDFILEINFO *ffi; + UINT ffi_len; + + if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) && + VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { + realMajor = HIWORD(ffi->dwProductVersionMS); + realMinor = LOWORD(ffi->dwProductVersionMS); + realBuild = HIWORD(ffi->dwProductVersionLS); + } + PyMem_RawFree(verblock); + } + PyStructSequence_SET_ITEM(version, pos++, PyTuple_Pack(3, + PyLong_FromLong(realMajor), + PyLong_FromLong(realMinor), + PyLong_FromLong(realBuild) + )); + if (PyErr_Occurred()) { Py_DECREF(version); return NULL; } + return version; } |