Handle errors when generating a warning.
The value is always written to the returned pointer if getting it was successful, even if a warning causes an error. (This probably doesn't matter as the caller will probably discard the value.) Will backport.
This commit is contained in:
parent
f3e93a0268
commit
2ef7582b52
|
@ -156,6 +156,12 @@ PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v
|
|||
return -1;
|
||||
}
|
||||
|
||||
#define WARN(msg) \
|
||||
do { \
|
||||
if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||
{
|
||||
|
@ -178,60 +184,54 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
addr += l->offset;
|
||||
switch (l->type) {
|
||||
case T_BYTE:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(char*)addr = (char)long_val;
|
||||
/* XXX: For compatibility, only warn about truncations
|
||||
for now. */
|
||||
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to char");
|
||||
*(char*)addr = (char)long_val;
|
||||
WARN("Truncation of value to char");
|
||||
break;
|
||||
}
|
||||
case T_UBYTE:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned char");
|
||||
*(unsigned char*)addr = (unsigned char)long_val;
|
||||
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
||||
WARN("Truncation of value to unsigned char");
|
||||
break;
|
||||
}
|
||||
case T_SHORT:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to short");
|
||||
*(short*)addr = (short)long_val;
|
||||
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
||||
WARN("Truncation of value to short");
|
||||
break;
|
||||
}
|
||||
case T_USHORT:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
if ((long_val > USHRT_MAX) || (long_val < 0))
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned short");
|
||||
*(unsigned short*)addr = (unsigned short)long_val;
|
||||
if ((long_val > USHRT_MAX) || (long_val < 0))
|
||||
WARN("Truncation of value to unsigned short");
|
||||
break;
|
||||
}
|
||||
case T_INT:{
|
||||
long long_val;
|
||||
long_val = PyInt_AsLong(v);
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to int");
|
||||
*(int *)addr = (int)long_val;
|
||||
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
||||
WARN("Truncation of value to int");
|
||||
break;
|
||||
}
|
||||
case T_UINT:{
|
||||
unsigned long ulong_val;
|
||||
ulong_val = PyLong_AsUnsignedLong(v);
|
||||
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
|
||||
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
|
||||
/* XXX: For compatibility, accept negative int values
|
||||
as well. */
|
||||
|
@ -239,11 +239,12 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
ulong_val = PyLong_AsLong(v);
|
||||
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
|
||||
return -1;
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
||||
}
|
||||
if (ulong_val > UINT_MAX)
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
|
||||
*(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;
|
||||
}
|
||||
case T_LONG:{
|
||||
|
@ -260,9 +261,10 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
as well. */
|
||||
PyErr_Clear();
|
||||
*(unsigned long*)addr = PyLong_AsLong(v);
|
||||
if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
|
||||
if ((*(unsigned long*)addr == (unsigned int)-1)
|
||||
&& PyErr_Occurred())
|
||||
return -1;
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
||||
WARN("Writing negative value into unsigned field");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -274,8 +276,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
break;
|
||||
}
|
||||
case T_FLOAT:{
|
||||
double double_val;
|
||||
double_val = PyFloat_AsDouble(v);
|
||||
double double_val = PyFloat_AsDouble(v);
|
||||
if ((double_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(float*)addr = (float)double_val;
|
||||
|
|
Loading…
Reference in New Issue