mirror of
https://github.com/python/cpython.git
synced 2025-08-19 16:20:59 +00:00
[Backport of r52452]
Patch #1549049: Rewrite type conversion in structmember. Fixes #1545696 and #1566140. The new warnings have been omitted in the backport.
This commit is contained in:
parent
1121e73536
commit
62e58040c1
4 changed files with 249 additions and 64 deletions
|
@ -62,29 +62,28 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)
|
|||
addr += l->offset;
|
||||
switch (l->type) {
|
||||
case T_BYTE:
|
||||
v = PyInt_FromLong(
|
||||
(long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80));
|
||||
v = PyInt_FromLong(*(char*)addr);
|
||||
break;
|
||||
case T_UBYTE:
|
||||
v = PyInt_FromLong((long) *(char*)addr & 0xff);
|
||||
v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
|
||||
break;
|
||||
case T_SHORT:
|
||||
v = PyInt_FromLong((long) *(short*)addr);
|
||||
v = PyInt_FromLong(*(short*)addr);
|
||||
break;
|
||||
case T_USHORT:
|
||||
v = PyInt_FromLong((long) *(unsigned short*)addr);
|
||||
v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
|
||||
break;
|
||||
case T_INT:
|
||||
v = PyInt_FromLong((long) *(int*)addr);
|
||||
v = PyInt_FromLong(*(int*)addr);
|
||||
break;
|
||||
case T_UINT:
|
||||
v = PyInt_FromLong((long) *(unsigned int*)addr);
|
||||
v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
|
||||
break;
|
||||
case T_LONG:
|
||||
v = PyInt_FromLong(*(long*)addr);
|
||||
break;
|
||||
case T_ULONG:
|
||||
v = PyLong_FromDouble((double) *(unsigned long*)addr);
|
||||
v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
|
||||
break;
|
||||
case T_FLOAT:
|
||||
v = PyFloat_FromDouble((double)*(float*)addr);
|
||||
|
@ -175,68 +174,91 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
}
|
||||
addr += l->offset;
|
||||
switch (l->type) {
|
||||
case T_BYTE:
|
||||
case T_UBYTE:
|
||||
if (!PyInt_Check(v)) {
|
||||
PyErr_BadArgument();
|
||||
case T_BYTE:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
}
|
||||
*(char*)addr = (char) PyInt_AsLong(v);
|
||||
*(char*)addr = (char)long_val;
|
||||
break;
|
||||
case T_SHORT:
|
||||
case T_USHORT:
|
||||
if (!PyInt_Check(v)) {
|
||||
PyErr_BadArgument();
|
||||
return -1;
|
||||
}
|
||||
*(short*)addr = (short) PyInt_AsLong(v);
|
||||
break;
|
||||
case T_UINT:
|
||||
case T_INT:
|
||||
if (!PyInt_Check(v)) {
|
||||
PyErr_BadArgument();
|
||||
case T_UBYTE:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned char*)addr = (unsigned char)long_val;
|
||||
break;
|
||||
}
|
||||
*(int*)addr = (int) PyInt_AsLong(v);
|
||||
break;
|
||||
case T_LONG:
|
||||
if (!PyInt_Check(v)) {
|
||||
PyErr_BadArgument();
|
||||
case T_SHORT:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(short*)addr = (short)long_val;
|
||||
break;
|
||||
}
|
||||
*(long*)addr = PyInt_AsLong(v);
|
||||
break;
|
||||
case T_ULONG:
|
||||
if (PyInt_Check(v))
|
||||
*(long*)addr = PyInt_AsLong(v);
|
||||
else if (PyLong_Check(v))
|
||||
*(long*)addr = PyLong_AsLong(v);
|
||||
else {
|
||||
PyErr_BadArgument();
|
||||
case T_USHORT:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned short*)addr = (unsigned short)long_val;
|
||||
break;
|
||||
}
|
||||
case T_INT:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(int *)addr = (int)long_val;
|
||||
break;
|
||||
}
|
||||
case T_UINT:{
|
||||
unsigned long ulong_val;
|
||||
ulong_val = PyLong_AsUnsignedLong(v);
|
||||
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
|
||||
/* XXX: For compatibility, accept negative int values
|
||||
as well. */
|
||||
PyErr_Clear();
|
||||
ulong_val = PyLong_AsLong(v);
|
||||
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
|
||||
return -1;
|
||||
}
|
||||
*(unsigned int *)addr = (unsigned int)ulong_val;
|
||||
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 int)-1) && PyErr_Occurred())
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case T_FLOAT:
|
||||
if (PyInt_Check(v))
|
||||
*(float*)addr =
|
||||
(float) PyInt_AsLong(v);
|
||||
else if (PyFloat_Check(v))
|
||||
*(float*)addr =
|
||||
(float) PyFloat_AsDouble(v);
|
||||
else {
|
||||
PyErr_BadArgument();
|
||||
return -1;
|
||||
}
|
||||
case T_FLOAT:{
|
||||
double double_val;
|
||||
double_val = PyFloat_AsDouble(v);
|
||||
if ((double_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(float*)addr = (float)double_val;
|
||||
break;
|
||||
}
|
||||
case T_DOUBLE:
|
||||
if (PyInt_Check(v))
|
||||
*(double*)addr = (double) PyInt_AsLong(v);
|
||||
else if (PyFloat_Check(v))
|
||||
*(double*)addr = PyFloat_AsDouble(v);
|
||||
else {
|
||||
PyErr_BadArgument();
|
||||
*(double*)addr = PyFloat_AsDouble(v);
|
||||
if ((*(double*)addr == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case T_OBJECT:
|
||||
case T_OBJECT_EX:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue