Skip to content

Commit c91bdf8

Browse files
authored
gh-116326: Handler errors correctly in getwindowsversion in sysmodule (#116339)
1 parent cbf3d38 commit c91bdf8

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

Python/sysmodule.c

+32-20
Original file line numberDiff line numberDiff line change
@@ -1643,12 +1643,13 @@ sys_getwindowsversion_impl(PyObject *module)
16431643
int pos = 0;
16441644
OSVERSIONINFOEXW ver;
16451645

1646-
version = PyObject_GetAttrString(module, "_cached_windows_version");
1646+
if (PyObject_GetOptionalAttrString(module, "_cached_windows_version", &version) < 0) {
1647+
return NULL;
1648+
};
16471649
if (version && PyObject_TypeCheck(version, &WindowsVersionType)) {
16481650
return version;
16491651
}
16501652
Py_XDECREF(version);
1651-
PyErr_Clear();
16521653

16531654
ver.dwOSVersionInfoSize = sizeof(ver);
16541655
if (!GetVersionExW((OSVERSIONINFOW*) &ver))
@@ -1658,22 +1659,35 @@ sys_getwindowsversion_impl(PyObject *module)
16581659
if (version == NULL)
16591660
return NULL;
16601661

1661-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion));
1662-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
1663-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
1664-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
1665-
PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1666-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
1667-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
1668-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
1669-
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
1662+
#define SET_VERSION_INFO(CALL) \
1663+
do { \
1664+
PyObject *item = (CALL); \
1665+
if (item == NULL) { \
1666+
goto error; \
1667+
} \
1668+
PyStructSequence_SET_ITEM(version, pos++, item); \
1669+
} while(0)
1670+
1671+
SET_VERSION_INFO(PyLong_FromLong(ver.dwMajorVersion));
1672+
SET_VERSION_INFO(PyLong_FromLong(ver.dwMinorVersion));
1673+
SET_VERSION_INFO(PyLong_FromLong(ver.dwBuildNumber));
1674+
SET_VERSION_INFO(PyLong_FromLong(ver.dwPlatformId));
1675+
SET_VERSION_INFO(PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1676+
SET_VERSION_INFO(PyLong_FromLong(ver.wServicePackMajor));
1677+
SET_VERSION_INFO(PyLong_FromLong(ver.wServicePackMinor));
1678+
SET_VERSION_INFO(PyLong_FromLong(ver.wSuiteMask));
1679+
SET_VERSION_INFO(PyLong_FromLong(ver.wProductType));
16701680

16711681
// GetVersion will lie if we are running in a compatibility mode.
16721682
// We need to read the version info from a system file resource
16731683
// to accurately identify the OS version. If we fail for any reason,
16741684
// just return whatever GetVersion said.
16751685
PyObject *realVersion = _sys_getwindowsversion_from_kernel32();
16761686
if (!realVersion) {
1687+
if (!PyErr_ExceptionMatches(PyExc_WindowsError)) {
1688+
return NULL;
1689+
}
1690+
16771691
PyErr_Clear();
16781692
realVersion = Py_BuildValue("(kkk)",
16791693
ver.dwMajorVersion,
@@ -1682,21 +1696,19 @@ sys_getwindowsversion_impl(PyObject *module)
16821696
);
16831697
}
16841698

1685-
if (realVersion) {
1686-
PyStructSequence_SET_ITEM(version, pos++, realVersion);
1687-
}
1699+
SET_VERSION_INFO(realVersion);
16881700

1689-
if (PyErr_Occurred()) {
1690-
Py_DECREF(version);
1691-
return NULL;
1692-
}
1701+
#undef SET_VERSION_INFO
16931702

16941703
if (PyObject_SetAttrString(module, "_cached_windows_version", version) < 0) {
1695-
Py_DECREF(version);
1696-
return NULL;
1704+
goto error;
16971705
}
16981706

16991707
return version;
1708+
1709+
error:
1710+
Py_DECREF(version);
1711+
return NULL;
17001712
}
17011713

17021714
#pragma warning(pop)

0 commit comments

Comments
 (0)