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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WARN(msg) \
|
||||||
|
do { \
|
||||||
|
if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0) \
|
||||||
|
return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
int
|
int
|
||||||
PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||||
{
|
{
|
||||||
|
@ -178,60 +184,54 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||||
addr += l->offset;
|
addr += l->offset;
|
||||||
switch (l->type) {
|
switch (l->type) {
|
||||||
case T_BYTE:{
|
case T_BYTE:{
|
||||||
long long_val;
|
long long_val = PyInt_AsLong(v);
|
||||||
long_val = PyInt_AsLong(v);
|
|
||||||
if ((long_val == -1) && PyErr_Occurred())
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
|
*(char*)addr = (char)long_val;
|
||||||
/* XXX: For compatibility, only warn about truncations
|
/* XXX: For compatibility, only warn about truncations
|
||||||
for now. */
|
for now. */
|
||||||
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
||||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to char");
|
WARN("Truncation of value to char");
|
||||||
*(char*)addr = (char)long_val;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_UBYTE:{
|
case T_UBYTE:{
|
||||||
long long_val;
|
long long_val = PyInt_AsLong(v);
|
||||||
long_val = PyInt_AsLong(v);
|
|
||||||
if ((long_val == -1) && PyErr_Occurred())
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
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;
|
*(unsigned char*)addr = (unsigned char)long_val;
|
||||||
|
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
||||||
|
WARN("Truncation of value to unsigned char");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_SHORT:{
|
case T_SHORT:{
|
||||||
long long_val;
|
long long_val = PyInt_AsLong(v);
|
||||||
long_val = PyInt_AsLong(v);
|
|
||||||
if ((long_val == -1) && PyErr_Occurred())
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
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;
|
*(short*)addr = (short)long_val;
|
||||||
|
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
||||||
|
WARN("Truncation of value to short");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_USHORT:{
|
case T_USHORT:{
|
||||||
long long_val;
|
long long_val = PyInt_AsLong(v);
|
||||||
long_val = PyInt_AsLong(v);
|
|
||||||
if ((long_val == -1) && PyErr_Occurred())
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
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;
|
*(unsigned short*)addr = (unsigned short)long_val;
|
||||||
|
if ((long_val > USHRT_MAX) || (long_val < 0))
|
||||||
|
WARN("Truncation of value to unsigned short");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_INT:{
|
case T_INT:{
|
||||||
long long_val;
|
long long_val = PyInt_AsLong(v);
|
||||||
long_val = PyInt_AsLong(v);
|
|
||||||
if ((long_val == -1) && PyErr_Occurred())
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
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;
|
*(int *)addr = (int)long_val;
|
||||||
|
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
||||||
|
WARN("Truncation of value to int");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_UINT:{
|
case T_UINT:{
|
||||||
unsigned long ulong_val;
|
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
|
||||||
ulong_val = PyLong_AsUnsignedLong(v);
|
|
||||||
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
|
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
|
||||||
/* XXX: For compatibility, accept negative int values
|
/* XXX: For compatibility, accept negative int values
|
||||||
as well. */
|
as well. */
|
||||||
|
@ -239,11 +239,12 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||||
ulong_val = PyLong_AsLong(v);
|
ulong_val = PyLong_AsLong(v);
|
||||||
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
|
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
*(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)
|
if (ulong_val > UINT_MAX)
|
||||||
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
|
WARN("Truncation of value to unsigned int");
|
||||||
*(unsigned int *)addr = (unsigned int)ulong_val;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_LONG:{
|
case T_LONG:{
|
||||||
|
@ -260,9 +261,10 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||||
as well. */
|
as well. */
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
*(unsigned long*)addr = PyLong_AsLong(v);
|
*(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;
|
return -1;
|
||||||
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
WARN("Writing negative value into unsigned field");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -274,8 +276,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_FLOAT:{
|
case T_FLOAT:{
|
||||||
double double_val;
|
double double_val = PyFloat_AsDouble(v);
|
||||||
double_val = PyFloat_AsDouble(v);
|
|
||||||
if ((double_val == -1) && PyErr_Occurred())
|
if ((double_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
*(float*)addr = (float)double_val;
|
*(float*)addr = (float)double_val;
|
||||||
|
|
Loading…
Reference in New Issue