summaryrefslogtreecommitdiffstats
path: root/Python/structmember.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/structmember.c')
-rw-r--r--Python/structmember.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/Python/structmember.c b/Python/structmember.c
index c9f03a4..ba881d1 100644
--- a/Python/structmember.c
+++ b/Python/structmember.c
@@ -2,6 +2,8 @@
/* Map C struct members to Python object attributes */
#include "Python.h"
+#include "pycore_abstract.h" // _PyNumber_Index()
+#include "pycore_long.h" // _PyLong_IsNegative()
PyObject *
@@ -200,27 +202,22 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
case Py_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");
+ v = _PyNumber_Index(v);
+ if (v == NULL) {
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");
+ if (_PyLong_IsNegative((PyLongObject *)v)) {
+ long long_val = PyLong_AsLong(v);
+ Py_DECREF(v);
+ if (long_val == -1 && PyErr_Occurred()) {
+ return -1;
}
+ *(unsigned int *)addr = (unsigned int)(unsigned long)long_val;
+ WARN("Writing negative value into unsigned field");
}
else {
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
+ Py_DECREF(v);
if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) {
return -1;
}
@@ -240,24 +237,22 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
case Py_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");
+ v = _PyNumber_Index(v);
+ if (v == NULL) {
return -1;
}
- else if (!overflow) {
- *(unsigned long *)addr = (unsigned long)long_val;
- if (long_val < 0) {
- WARN("Writing negative value into unsigned field");
+ if (_PyLong_IsNegative((PyLongObject *)v)) {
+ long long_val = PyLong_AsLong(v);
+ Py_DECREF(v);
+ if (long_val == -1 && PyErr_Occurred()) {
+ return -1;
}
+ *(unsigned long *)addr = (unsigned long)long_val;
+ WARN("Writing negative value into unsigned field");
}
else {
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
+ Py_DECREF(v);
if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) {
return -1;
}
@@ -313,18 +308,30 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
return -1;
break;
}
- case Py_T_ULONGLONG:{
- unsigned long long value;
- /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
- doesn't ??? */
- if (PyLong_Check(v))
- *(unsigned long long*)addr = value = PyLong_AsUnsignedLongLong(v);
- else
- *(unsigned long long*)addr = value = PyLong_AsLong(v);
- if ((value == (unsigned long long)-1) && PyErr_Occurred())
+ case Py_T_ULONGLONG: {
+ v = _PyNumber_Index(v);
+ if (v == NULL) {
return -1;
- break;
}
+ if (_PyLong_IsNegative((PyLongObject *)v)) {
+ long long_val = PyLong_AsLong(v);
+ Py_DECREF(v);
+ if (long_val == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ *(unsigned long long *)addr = (unsigned long long)(long long)long_val;
+ WARN("Writing negative value into unsigned field");
+ }
+ else {
+ unsigned long long ulonglong_val = PyLong_AsUnsignedLongLong(v);
+ Py_DECREF(v);
+ if (ulonglong_val == (unsigned long long)-1 && PyErr_Occurred()) {
+ return -1;
+ }
+ *(unsigned long long*)addr = ulonglong_val;
+ }
+ break;
+ }
default:
PyErr_Format(PyExc_SystemError,
"bad memberdescr type for %s", l->name);