mirror of
https://github.com/python/cpython.git
synced 2025-07-19 01:05:26 +00:00
Issue #27932: Prevent memory leak in win32_ver().
This commit is contained in:
parent
1374053127
commit
74f4af7ac3
5 changed files with 57 additions and 81 deletions
|
@ -894,10 +894,11 @@ Return information about the running version of Windows as a named tuple.\n\
|
|||
The members are named: major, minor, build, platform, service_pack,\n\
|
||||
service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\
|
||||
backward compatibility, only the first 5 items are available by indexing.\n\
|
||||
All elements are numbers, except service_pack which is a string. Platform\n\
|
||||
may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n\
|
||||
3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n\
|
||||
controller, 3 for a server."
|
||||
All elements are numbers, except service_pack and platform_type which are\n\
|
||||
strings, and platform_version which is a 3-tuple. Platform is always 2.\n\
|
||||
Product_type may be 1 for a workstation, 2 for a domain controller, 3 for a\n\
|
||||
server. Platform_version is a 3-tuple containing a version number that is\n\
|
||||
intended for identifying the OS rather than feature detection."
|
||||
);
|
||||
|
||||
static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
|
||||
|
@ -912,6 +913,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}
|
||||
};
|
||||
|
||||
|
@ -936,6 +938,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);
|
||||
|
@ -954,10 +962,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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue