diff options
-rw-r--r-- | Modules/arraymodule.c | 105 |
1 files changed, 95 insertions, 10 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 7966e0a..96ec793 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -114,11 +114,24 @@ b_setitem(ap, i, v) int i; PyObject *v; { - char x; - if (!PyArg_Parse(v, "b;array item must be integer", &x)) + short x; + /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore + must use the next size up that is signed ('h') and manually do + the overflow checking */ + if (!PyArg_Parse(v, "h;array item must be integer", &x)) + return -1; + else if (x < CHAR_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed char is less than minimum"); + return -1; + } + else if (x > CHAR_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed char is greater than maximum"); return -1; + } if (i >= 0) - ((char *)ap->ob_item)[i] = x; + ((char *)ap->ob_item)[i] = (char)x; return 0; } @@ -131,7 +144,20 @@ BB_getitem(ap, i) return PyInt_FromLong(x); } -#define BB_setitem b_setitem +static int +BB_setitem(ap, i, v) + arrayobject *ap; + int i; + PyObject *v; +{ + unsigned char x; + /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */ + if (!PyArg_Parse(v, "b;array item must be integer", &x)) + return -1; + if (i >= 0) + ((char *)ap->ob_item)[i] = x; + return 0; +} static PyObject * h_getitem(ap, i) @@ -148,6 +174,7 @@ h_setitem(ap, i, v) PyObject *v; { short x; + /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */ if (!PyArg_Parse(v, "h;array item must be integer", &x)) return -1; if (i >= 0) @@ -163,7 +190,31 @@ HH_getitem(ap, i) return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]); } -#define HH_setitem h_setitem +static int +HH_setitem(ap, i, v) + arrayobject *ap; + int i; + PyObject *v; +{ + int x; + /* PyArg_Parse's 'h' formatter is for a signed short, therefore + must use the next size up and manually do the overflow checking */ + if (!PyArg_Parse(v, "i;array item must be integer", &x)) + return -1; + else if (x < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned short is less than minimum"); + return -1; + } + else if (x > USHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned short is greater than maximum"); + return -1; + } + if (i >= 0) + ((short *)ap->ob_item)[i] = (short)x; + return 0; +} static PyObject * i_getitem(ap, i) @@ -180,6 +231,7 @@ i_setitem(ap, i, v) PyObject *v; { int x; + /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */ if (!PyArg_Parse(v, "i;array item must be integer", &x)) return -1; if (i >= 0) @@ -209,11 +261,25 @@ II_setitem(ap, i, v) return -1; } else { - if (!PyArg_Parse(v, "l;array item must be integer", &x)) + long y; + if (!PyArg_Parse(v, "l;array item must be integer", &y)) return -1; + if (y < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned int is less than minimum"); + return -1; + } + x = (unsigned long)y; + + } + if (x > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned int is greater than maximum"); + return -1; } + if (i >= 0) - ((unsigned int *)ap->ob_item)[i] = x; + ((unsigned int *)ap->ob_item)[i] = (unsigned int)x; return 0; } @@ -260,9 +326,23 @@ LL_setitem(ap, i, v) return -1; } else { - if (!PyArg_Parse(v, "l;array item must be integer", &x)) + long y; + if (!PyArg_Parse(v, "l;array item must be integer", &y)) + return -1; + if (y < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned long is less than minimum"); return -1; + } + x = (unsigned long)y; + + } + if (x > ULONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned long is greater than maximum"); + return -1; } + if (i >= 0) ((unsigned long *)ap->ob_item)[i] = x; return 0; @@ -725,8 +805,13 @@ array_buffer_info(self, args) arrayobject *self; PyObject *args; { - return Py_BuildValue("ll", - (long)(self->ob_item), (long)(self->ob_size)); + PyObject* retval = PyTuple_New(2); + if (!retval) return NULL; + + PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item)); + PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size))); + + return retval; } static char buffer_info_doc [] = |