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:
Neal Norwitz 2007-08-05 03:23:31 +00:00
parent f3e93a0268
commit 2ef7582b52
1 changed files with 31 additions and 30 deletions

View File

@ -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");
}
*(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)
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
*(unsigned int *)addr = (unsigned int)ulong_val;
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;