From 2ef7582b52ad2a08d633d01c3f77734eabe13159 Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Sun, 5 Aug 2007 03:23:31 +0000 Subject: [PATCH] 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. --- Python/structmember.c | 61 ++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/Python/structmember.c b/Python/structmember.c index 4da0c7861c3..7cfa620a176 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -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;