summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/arraymodule.c105
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 [] =