@@ -151,10 +151,16 @@ enum machine_format_code {
151151
152152#define array_Check (op , state ) PyObject_TypeCheck(op, state->ArrayType)
153153
154+ static inline bool
155+ arraydata_size_valid (Py_ssize_t size , int itemsize )
156+ {
157+ return size <= (PY_SSIZE_T_MAX - sizeof (arraydata )) / itemsize ;
158+ }
159+
154160static arraydata *
155161arraydata_alloc (Py_ssize_t size , int itemsize )
156162{
157- assert (size <= PY_SSIZE_T_MAX / itemsize );
163+ assert (arraydata_size_valid ( size , itemsize ) );
158164 Py_ssize_t bufsize = sizeof (arraydata ) + size * itemsize ;
159165 arraydata * data = (arraydata * )PyMem_Malloc (bufsize );
160166 if (data == NULL ) {
@@ -265,7 +271,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
265271
266272 /* XXX The following multiplication and division does not optimize away
267273 like it does for lists since the size is not known at compile time */
268- if (_new_size > ((~( size_t ) 0 ) / itemsize )) {
274+ if (! arraydata_size_valid ( _new_size , itemsize )) {
269275 PyErr_NoMemory ();
270276 return -1 ;
271277 }
@@ -745,7 +751,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
745751 }
746752
747753 /* Check for overflow */
748- if (size > PY_SSIZE_T_MAX / descr -> itemsize ) {
754+ if (! arraydata_size_valid ( size , descr -> itemsize ) ) {
749755 return PyErr_NoMemory ();
750756 }
751757 op = (arrayobject * ) type -> tp_alloc (type , 0 );
@@ -1368,7 +1374,7 @@ array_do_extend_lock_held(array_state *state, arrayobject *self, PyObject *bb)
13681374 return -1 ;
13691375 }
13701376 if ((Py_SIZE (self ) > PY_SSIZE_T_MAX - Py_SIZE (b )) ||
1371- (( Py_SIZE (self ) + Py_SIZE (b )) > PY_SSIZE_T_MAX / self -> ob_descr -> itemsize )) {
1377+ ! arraydata_size_valid ( Py_SIZE (self ) + Py_SIZE (b ), self -> ob_descr -> itemsize )) {
13721378 PyErr_NoMemory ();
13731379 return -1 ;
13741380 }
@@ -1424,6 +1430,7 @@ array_inplace_repeat_lock_held(PyObject *op, Py_ssize_t n)
14241430 if (array_size > 0 && n != 1 ) {
14251431 if (n < 0 )
14261432 n = 0 ;
1433+ // XXX This check below does nothing useful???
14271434 if ((self -> ob_descr -> itemsize != 0 ) &&
14281435 (array_size > PY_SSIZE_T_MAX / self -> ob_descr -> itemsize )) {
14291436 return PyErr_NoMemory ();
@@ -1848,15 +1855,15 @@ array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f,
18481855/*[clinic end generated code: output=83a667080b345ebc input=3822e907c1c11f1a]*/
18491856{
18501857 PyObject * b , * res ;
1851- Py_ssize_t itemsize = self -> ob_descr -> itemsize ;
1858+ int itemsize = self -> ob_descr -> itemsize ;
18521859 Py_ssize_t nbytes ;
18531860 int not_enough_bytes ;
18541861
18551862 if (n < 0 ) {
18561863 PyErr_SetString (PyExc_ValueError , "negative count" );
18571864 return NULL ;
18581865 }
1859- if (n > PY_SSIZE_T_MAX / itemsize ) {
1866+ if (! arraydata_size_valid ( n , itemsize ) ) {
18601867 PyErr_NoMemory ();
18611868 return NULL ;
18621869 }
@@ -2048,7 +2055,7 @@ array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
20482055 if (n > 0 ) {
20492056 Py_ssize_t old_size = Py_SIZE (self );
20502057 if ((n > PY_SSIZE_T_MAX - old_size ) ||
2051- (( old_size + n ) > PY_SSIZE_T_MAX / itemsize )) {
2058+ ! arraydata_size_valid ( old_size + n , itemsize )) {
20522059 return PyErr_NoMemory ();
20532060 }
20542061 if (array_resize (self , old_size + n ) == -1 ) {
@@ -2071,7 +2078,7 @@ static PyObject *
20712078array_array_tobytes_impl (arrayobject * self )
20722079/*[clinic end generated code: output=87318e4edcdc2bb6 input=c4d44d5499d2320f]*/
20732080{
2074- if (Py_SIZE (self ) <= PY_SSIZE_T_MAX / self -> ob_descr -> itemsize ) {
2081+ if (arraydata_size_valid ( Py_SIZE (self ), self -> ob_descr -> itemsize ) ) {
20752082 return PyBytes_FromStringAndSize (array_items_ptr (self ),
20762083 Py_SIZE (self ) * self -> ob_descr -> itemsize );
20772084 } else {
@@ -2125,7 +2132,7 @@ array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
21252132 Py_ssize_t old_size = Py_SIZE (self );
21262133 Py_ssize_t new_size = old_size + ustr_length ;
21272134
2128- if (new_size < 0 || ( size_t ) new_size > PY_SSIZE_T_MAX / sizeof (Py_UCS4 )) {
2135+ if (new_size < 0 || ! arraydata_size_valid ( new_size , sizeof (Py_UCS4 ) )) {
21292136 return PyErr_NoMemory ();
21302137 }
21312138 if (array_resize (self , new_size ) == -1 ) {
0 commit comments