summaryrefslogtreecommitdiff
path: root/Modules/arraymodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r--Modules/arraymodule.c122
1 files changed, 81 insertions, 41 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 3aba9adbeb..4a1c158514 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -513,7 +513,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
static PyObject *
getarrayitem(PyObject *op, Py_ssize_t i)
{
- register arrayobject *ap;
+ arrayobject *ap;
assert(array_Check(op));
ap = (arrayobject *)op;
assert(i>=0 && i<Py_SIZE(ap));
@@ -968,8 +968,13 @@ array_count(arrayobject *self, PyObject *v)
Py_ssize_t i;
for (i = 0; i < Py_SIZE(self); i++) {
- PyObject *selfi = getarrayitem((PyObject *)self, i);
- int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ PyObject *selfi;
+ int cmp;
+
+ selfi = getarrayitem((PyObject *)self, i);
+ if (selfi == NULL)
+ return NULL;
+ cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Py_DECREF(selfi);
if (cmp > 0)
count++;
@@ -990,8 +995,13 @@ array_index(arrayobject *self, PyObject *v)
Py_ssize_t i;
for (i = 0; i < Py_SIZE(self); i++) {
- PyObject *selfi = getarrayitem((PyObject *)self, i);
- int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ PyObject *selfi;
+ int cmp;
+
+ selfi = getarrayitem((PyObject *)self, i);
+ if (selfi == NULL)
+ return NULL;
+ cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Py_DECREF(selfi);
if (cmp > 0) {
return PyLong_FromLong((long)i);
@@ -1016,6 +1026,8 @@ array_contains(arrayobject *self, PyObject *v)
for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
PyObject *selfi = getarrayitem((PyObject *)self, i);
+ if (selfi == NULL)
+ return -1;
cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Py_DECREF(selfi);
}
@@ -1028,8 +1040,13 @@ array_remove(arrayobject *self, PyObject *v)
int i;
for (i = 0; i < Py_SIZE(self); i++) {
- PyObject *selfi = getarrayitem((PyObject *)self,i);
- int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ PyObject *selfi;
+ int cmp;
+
+ selfi = getarrayitem((PyObject *)self,i);
+ if (selfi == NULL)
+ return NULL;
+ cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Py_DECREF(selfi);
if (cmp > 0) {
if (array_ass_slice(self, i, i+1,
@@ -1068,7 +1085,9 @@ array_pop(arrayobject *self, PyObject *args)
PyErr_SetString(PyExc_IndexError, "pop index out of range");
return NULL;
}
- v = getarrayitem((PyObject *)self,i);
+ v = getarrayitem((PyObject *)self, i);
+ if (v == NULL)
+ return NULL;
if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
Py_DECREF(v);
return NULL;
@@ -1114,13 +1133,25 @@ Insert a new item x into the array before position i.");
static PyObject *
array_buffer_info(arrayobject *self, PyObject *unused)
{
- PyObject* retval = NULL;
+ PyObject *retval = NULL, *v;
+
retval = PyTuple_New(2);
if (!retval)
return NULL;
- PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
- PyTuple_SET_ITEM(retval, 1, PyLong_FromLong((long)(Py_SIZE(self))));
+ v = PyLong_FromVoidPtr(self->ob_item);
+ if (v == NULL) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(retval, 0, v);
+
+ v = PyLong_FromLong((long)(Py_SIZE(self)));
+ if (v == NULL) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(retval, 1, v);
return retval;
}
@@ -1206,8 +1237,8 @@ Byteswap all items of the array. If the items in the array are not 1, 2,\n\
static PyObject *
array_reverse(arrayobject *self, PyObject *unused)
{
- register Py_ssize_t itemsize = self->ob_descr->itemsize;
- register char *p, *q;
+ Py_ssize_t itemsize = self->ob_descr->itemsize;
+ char *p, *q;
/* little buffer to hold items while swapping */
char tmp[256]; /* 8 is probably enough -- but why skimp */
assert((size_t)itemsize <= sizeof(tmp));
@@ -1386,13 +1417,16 @@ array_tolist(arrayobject *self, PyObject *unused)
return NULL;
for (i = 0; i < Py_SIZE(self); i++) {
PyObject *v = getarrayitem((PyObject *)self, i);
- if (v == NULL) {
- Py_DECREF(list);
- return NULL;
- }
- PyList_SetItem(list, i, v);
+ if (v == NULL)
+ goto error;
+ if (PyList_SetItem(list, i, v) < 0)
+ goto error;
}
return list;
+
+error:
+ Py_DECREF(list);
+ return NULL;
}
PyDoc_STRVAR(tolist_doc,
@@ -1664,11 +1698,8 @@ static const struct mformatdescr {
static enum machine_format_code
typecode_to_mformat_code(char typecode)
{
-#ifdef WORDS_BIGENDIAN
- const int is_big_endian = 1;
-#else
- const int is_big_endian = 0;
-#endif
+ const int is_big_endian = PY_BIG_ENDIAN;
+
size_t intsize;
int is_signed;
@@ -2487,6 +2518,20 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
return NULL;
+ if (initial && c != 'u') {
+ if (PyUnicode_Check(initial)) {
+ PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
+ "an array with typecode '%c'", c);
+ return NULL;
+ }
+ else if (array_Check(initial) &&
+ ((arrayobject*)initial)->ob_descr->typecode == 'u') {
+ PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
+ "initialize an array with typecode '%c'", c);
+ return NULL;
+ }
+ }
+
if (!(initial == NULL || PyList_Check(initial)
|| PyByteArray_Check(initial)
|| PyBytes_Check(initial)
@@ -2613,9 +2658,19 @@ PyDoc_STRVAR(module_doc,
"This module defines an object type which can efficiently represent\n\
an array of basic values: characters, integers, floating point\n\
numbers. Arrays are sequence types and behave very much like lists,\n\
-except that the type of objects stored in them is constrained. The\n\
-type is specified at object creation time by using a type code, which\n\
-is a single character. The following type codes are defined:\n\
+except that the type of objects stored in them is constrained.\n");
+
+PyDoc_STRVAR(arraytype_doc,
+"array(typecode [, initializer]) -> array\n\
+\n\
+Return a new array whose items are restricted by typecode, and\n\
+initialized from the optional initializer value, which must be a list,\n\
+string or iterable over elements of the appropriate type.\n\
+\n\
+Arrays represent basic values and behave very much like lists, except\n\
+the type of objects stored in them is constrained. The type is specified\n\
+at object creation time by using a type code, which is a single character.\n\
+The following type codes are defined:\n\
\n\
Type code C Type Minimum size in bytes \n\
'b' signed integer 1 \n\
@@ -2639,21 +2694,6 @@ NOTE: The 'q' and 'Q' type codes are only available if the platform \n\
C compiler used to build Python supports 'long long', or, on Windows, \n\
'__int64'.\n\
\n\
-The constructor is:\n\
-\n\
-array(typecode [, initializer]) -- create a new array\n\
-");
-
-PyDoc_STRVAR(arraytype_doc,
-"array(typecode [, initializer]) -> array\n\
-\n\
-Return a new array whose items are restricted by typecode, and\n\
-initialized from the optional initializer value, which must be a list,\n\
-string or iterable over elements of the appropriate type.\n\
-\n\
-Arrays represent basic values and behave very much like lists, except\n\
-the type of objects stored in them is constrained.\n\
-\n\
Methods:\n\
\n\
append() -- append a new item to the end of the array\n\