summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-02-04 17:21:05 (GMT)
committerGitHub <noreply@github.com>2024-02-04 17:21:05 (GMT)
commitb9937a6f22d3a3b555ec34321acfac189e79a842 (patch)
tree8c4ceca403ddca7c3580926f9a927f654c14e699 /Python
parent4548ae7e65a919516939548932644a16a2bdc329 (diff)
downloadcpython-b9937a6f22d3a3b555ec34321acfac189e79a842.zip
cpython-b9937a6f22d3a3b555ec34321acfac189e79a842.tar.gz
cpython-b9937a6f22d3a3b555ec34321acfac189e79a842.tar.bz2
[3.12] gh-114388: Fix warnings when assign an unsigned integer member (GH-114391) (GH-115001)
* Fix a RuntimeWarning emitted when assign an integer-like value that is not an instance of int to an attribute that corresponds to a C struct member of type T_UINT and T_ULONG. * Fix a double RuntimeWarning emitted when assign a negative integer value to an attribute that corresponds to a C struct member of type T_UINT. (cherry picked from commit 3ddc5152550ea62280124c37d0b4339030ff7df4)
Diffstat (limited to 'Python')
-rw-r--r--Python/structmember.c85
1 files changed, 57 insertions, 28 deletions
diff --git a/Python/structmember.c b/Python/structmember.c
index 19a7522..ebebaa0 100644
--- a/Python/structmember.c
+++ b/Python/structmember.c
@@ -197,45 +197,74 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
WARN("Truncation of value to int");
break;
}
- case T_UINT:{
- unsigned long ulong_val = PyLong_AsUnsignedLong(v);
- if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
- /* XXX: For compatibility, accept negative int values
- as well. */
- PyErr_Clear();
- ulong_val = PyLong_AsLong(v);
- if ((ulong_val == (unsigned long)-1) &&
- PyErr_Occurred())
+ case T_UINT: {
+ /* XXX: For compatibility, accept negative int values
+ as well. */
+ int overflow;
+ long long_val = PyLong_AsLongAndOverflow(v, &overflow);
+ if (long_val == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ if (overflow < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C long");
+ return -1;
+ }
+ else if (!overflow) {
+ *(unsigned int *)addr = (unsigned int)(unsigned long)long_val;
+ if (long_val < 0) {
+ WARN("Writing negative value into unsigned field");
+ }
+ else if ((unsigned long)long_val > UINT_MAX) {
+ WARN("Truncation of value to unsigned short");
+ }
+ }
+ else {
+ unsigned long ulong_val = PyLong_AsUnsignedLong(v);
+ if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) {
return -1;
- *(unsigned int *)addr = (unsigned int)ulong_val;
- WARN("Writing negative value into unsigned field");
- } else
- *(unsigned int *)addr = (unsigned int)ulong_val;
- if (ulong_val > UINT_MAX)
- WARN("Truncation of value to unsigned int");
- break;
+ }
+ *(unsigned int*)addr = (unsigned int)ulong_val;
+ if (ulong_val > UINT_MAX) {
+ WARN("Truncation of value to unsigned int");
+ }
}
+ break;
+ }
case T_LONG:{
*(long*)addr = PyLong_AsLong(v);
if ((*(long*)addr == -1) && PyErr_Occurred())
return -1;
break;
}
- case T_ULONG:{
- *(unsigned long*)addr = PyLong_AsUnsignedLong(v);
- if ((*(unsigned long*)addr == (unsigned long)-1)
- && PyErr_Occurred()) {
- /* XXX: For compatibility, accept negative int values
- as well. */
- PyErr_Clear();
- *(unsigned long*)addr = PyLong_AsLong(v);
- if ((*(unsigned long*)addr == (unsigned long)-1)
- && PyErr_Occurred())
+ case T_ULONG: {
+ /* XXX: For compatibility, accept negative int values
+ as well. */
+ int overflow;
+ long long_val = PyLong_AsLongAndOverflow(v, &overflow);
+ if (long_val == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ if (overflow < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C long");
+ return -1;
+ }
+ else if (!overflow) {
+ *(unsigned long *)addr = (unsigned long)long_val;
+ if (long_val < 0) {
+ WARN("Writing negative value into unsigned field");
+ }
+ }
+ else {
+ unsigned long ulong_val = PyLong_AsUnsignedLong(v);
+ if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) {
return -1;
- WARN("Writing negative value into unsigned field");
+ }
+ *(unsigned long*)addr = ulong_val;
}
break;
- }
+ }
case T_PYSSIZET:{
*(Py_ssize_t*)addr = PyLong_AsSsize_t(v);
if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)