@@ -49,9 +49,15 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
4949 char * items ;
5050 size_t _new_size ;
5151
52+ if (self -> ob_exports > 0 && newsize != Py_SIZE (self )) {
53+ PyErr_SetString (PyExc_BufferError ,
54+ "cannot resize an array that is exporting buffers" );
55+ return -1 ;
56+ }
57+
5258 /* Bypass realloc() when a previous overallocation is large enough
5359 to accommodate the newsize. If the newsize is 16 smaller than the
54- current size, then proceed with the realloc() to shrink the list .
60+ current size, then proceed with the realloc() to shrink the array .
5561 */
5662
5763 if (self -> allocated >= newsize &&
@@ -61,11 +67,13 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
6167 return 0 ;
6268 }
6369
64- if (self -> ob_exports > 0 ) {
65- PyErr_SetString (PyExc_BufferError ,
66- "cannot resize an array that is exporting data" );
67- return -1 ;
68- }
70+ if (newsize == 0 ) {
71+ PyMem_FREE (self -> ob_item );
72+ self -> ob_item = NULL ;
73+ Py_SIZE (self ) = 0 ;
74+ self -> allocated = 0 ;
75+ return 0 ;
76+ }
6977
7078 /* This over-allocates proportional to the array size, making room
7179 * for additional growth. The over-allocation is mild, but is
@@ -731,25 +739,15 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
731739 memmove (item + (ihigh + d )* a -> ob_descr -> itemsize ,
732740 item + ihigh * a -> ob_descr -> itemsize ,
733741 (Py_SIZE (a )- ihigh )* a -> ob_descr -> itemsize );
734- Py_SIZE (a ) += d ;
735- PyMem_RESIZE (item , char , Py_SIZE (a )* a -> ob_descr -> itemsize );
736- /* Can't fail */
737- a -> ob_item = item ;
738- a -> allocated = Py_SIZE (a );
742+ if (array_resize (a , Py_SIZE (a ) + d ) == -1 )
743+ return -1 ;
739744 }
740745 else if (d > 0 ) { /* Insert d items */
741- PyMem_RESIZE (item , char ,
742- (Py_SIZE (a ) + d )* a -> ob_descr -> itemsize );
743- if (item == NULL ) {
744- PyErr_NoMemory ();
746+ if (array_resize (a , Py_SIZE (a ) + d ))
745747 return -1 ;
746- }
747748 memmove (item + (ihigh + d )* a -> ob_descr -> itemsize ,
748749 item + ihigh * a -> ob_descr -> itemsize ,
749750 (Py_SIZE (a )- ihigh )* a -> ob_descr -> itemsize );
750- a -> ob_item = item ;
751- Py_SIZE (a ) += d ;
752- a -> allocated = Py_SIZE (a );
753751 }
754752 if (n > 0 )
755753 memcpy (item + ilow * a -> ob_descr -> itemsize , b -> ob_item ,
@@ -804,8 +802,7 @@ array_iter_extend(arrayobject *self, PyObject *bb)
804802static int
805803array_do_extend (arrayobject * self , PyObject * bb )
806804{
807- Py_ssize_t size ;
808- char * old_item ;
805+ Py_ssize_t size , oldsize ;
809806
810807 if (!array_Check (bb ))
811808 return array_iter_extend (self , bb );
@@ -820,18 +817,12 @@ array_do_extend(arrayobject *self, PyObject *bb)
820817 PyErr_NoMemory ();
821818 return -1 ;
822819 }
823- size = Py_SIZE (self ) + Py_SIZE (b );
824- old_item = self -> ob_item ;
825- PyMem_RESIZE (self -> ob_item , char , size * self -> ob_descr -> itemsize );
826- if (self -> ob_item == NULL ) {
827- self -> ob_item = old_item ;
828- PyErr_NoMemory ();
820+ oldsize = Py_SIZE (self );
821+ size = oldsize + Py_SIZE (b );
822+ if (array_resize (self , size ) == -1 )
829823 return -1 ;
830- }
831- memcpy (self -> ob_item + Py_SIZE (self )* self -> ob_descr -> itemsize ,
832- b -> ob_item , Py_SIZE (b )* b -> ob_descr -> itemsize );
833- Py_SIZE (self ) = size ;
834- self -> allocated = size ;
824+ memcpy (self -> ob_item + oldsize * self -> ob_descr -> itemsize ,
825+ b -> ob_item , Py_SIZE (b ) * b -> ob_descr -> itemsize );
835826
836827 return 0 ;
837828#undef b
@@ -867,27 +858,15 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n)
867858 return PyErr_NoMemory ();
868859 }
869860 size = Py_SIZE (self ) * self -> ob_descr -> itemsize ;
870- if (n == 0 ) {
871- PyMem_FREE (items );
872- self -> ob_item = NULL ;
873- Py_SIZE (self ) = 0 ;
874- self -> allocated = 0 ;
861+ if (n > 0 && size > PY_SSIZE_T_MAX / n ) {
862+ return PyErr_NoMemory ();
875863 }
876- else {
877- if (size > PY_SSIZE_T_MAX / n ) {
878- return PyErr_NoMemory ();
879- }
880- PyMem_RESIZE (items , char , n * size );
881- if (items == NULL )
882- return PyErr_NoMemory ();
883- p = items ;
884- for (i = 1 ; i < n ; i ++ ) {
885- p += size ;
886- memcpy (p , items , size );
887- }
888- self -> ob_item = items ;
889- Py_SIZE (self ) *= n ;
890- self -> allocated = Py_SIZE (self );
864+ if (array_resize (self , n * Py_SIZE (self )) == -1 )
865+ return NULL ;
866+ items = p = self -> ob_item ;
867+ for (i = 1 ; i < n ; i ++ ) {
868+ p += size ;
869+ memcpy (p , items , size );
891870 }
892871 }
893872 Py_INCREF (self );
@@ -1312,36 +1291,22 @@ static PyObject *
13121291array_fromlist (arrayobject * self , PyObject * list )
13131292{
13141293 Py_ssize_t n ;
1315- Py_ssize_t itemsize = self -> ob_descr -> itemsize ;
13161294
13171295 if (!PyList_Check (list )) {
13181296 PyErr_SetString (PyExc_TypeError , "arg must be list" );
13191297 return NULL ;
13201298 }
13211299 n = PyList_Size (list );
13221300 if (n > 0 ) {
1323- char * item = self -> ob_item ;
1324- Py_ssize_t i ;
1325- PyMem_RESIZE (item , char , (Py_SIZE (self ) + n ) * itemsize );
1326- if (item == NULL ) {
1327- PyErr_NoMemory ();
1301+ Py_ssize_t i , old_size ;
1302+ old_size = Py_SIZE (self );
1303+ if (array_resize (self , old_size + n ) == -1 )
13281304 return NULL ;
1329- }
1330- self -> ob_item = item ;
1331- Py_SIZE (self ) += n ;
1332- self -> allocated = Py_SIZE (self );
13331305 for (i = 0 ; i < n ; i ++ ) {
13341306 PyObject * v = PyList_GetItem (list , i );
13351307 if ((* self -> ob_descr -> setitem )(self ,
13361308 Py_SIZE (self ) - n + i , v ) != 0 ) {
1337- Py_SIZE (self ) -= n ;
1338- if (itemsize && (Py_SIZE (self ) > PY_SSIZE_T_MAX / itemsize )) {
1339- return PyErr_NoMemory ();
1340- }
1341- PyMem_RESIZE (item , char ,
1342- Py_SIZE (self ) * itemsize );
1343- self -> ob_item = item ;
1344- self -> allocated = Py_SIZE (self );
1309+ array_resize (self , old_size );
13451310 return NULL ;
13461311 }
13471312 }
@@ -1395,21 +1360,15 @@ array_fromstring(arrayobject *self, PyObject *args)
13951360 }
13961361 n = n / itemsize ;
13971362 if (n > 0 ) {
1398- char * item = self -> ob_item ;
1399- if ((n > PY_SSIZE_T_MAX - Py_SIZE ( self ) ) ||
1400- ((Py_SIZE ( self ) + n ) > PY_SSIZE_T_MAX / itemsize )) {
1363+ Py_ssize_t old_size = Py_SIZE ( self ) ;
1364+ if ((n > PY_SSIZE_T_MAX - old_size ) ||
1365+ ((old_size + n ) > PY_SSIZE_T_MAX / itemsize )) {
14011366 return PyErr_NoMemory ();
14021367 }
1403- PyMem_RESIZE (item , char , (Py_SIZE (self ) + n ) * itemsize );
1404- if (item == NULL ) {
1405- PyErr_NoMemory ();
1368+ if (array_resize (self , old_size + n ) == -1 )
14061369 return NULL ;
1407- }
1408- self -> ob_item = item ;
1409- Py_SIZE (self ) += n ;
1410- self -> allocated = Py_SIZE (self );
1411- memcpy (item + (Py_SIZE (self ) - n ) * itemsize ,
1412- str , itemsize * n );
1370+ memcpy (self -> ob_item + old_size * itemsize ,
1371+ str , n * itemsize );
14131372 }
14141373 Py_INCREF (Py_None );
14151374 return Py_None ;
@@ -1458,19 +1417,10 @@ array_fromunicode(arrayobject *self, PyObject *args)
14581417 return NULL ;
14591418 }
14601419 if (n > 0 ) {
1461- Py_UNICODE * item = (Py_UNICODE * ) self -> ob_item ;
1462- if (Py_SIZE (self ) > PY_SSIZE_T_MAX - n ) {
1463- return PyErr_NoMemory ();
1464- }
1465- PyMem_RESIZE (item , Py_UNICODE , Py_SIZE (self ) + n );
1466- if (item == NULL ) {
1467- PyErr_NoMemory ();
1420+ Py_ssize_t old_size = Py_SIZE (self );
1421+ if (array_resize (self , old_size + n ) == -1 )
14681422 return NULL ;
1469- }
1470- self -> ob_item = (char * ) item ;
1471- Py_SIZE (self ) += n ;
1472- self -> allocated = Py_SIZE (self );
1473- memcpy (item + Py_SIZE (self ) - n ,
1423+ memcpy (self -> ob_item + old_size * sizeof (Py_UNICODE ),
14741424 ustr , n * sizeof (Py_UNICODE ));
14751425 }
14761426
@@ -1740,12 +1690,12 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
17401690 self -> ob_item + stop * itemsize ,
17411691 (Py_SIZE (self ) - stop ) * itemsize );
17421692 if (array_resize (self , Py_SIZE (self ) +
1743- needed - slicelength ) < 0 )
1693+ needed - slicelength ) < 0 )
17441694 return -1 ;
17451695 }
17461696 else if (slicelength < needed ) {
17471697 if (array_resize (self , Py_SIZE (self ) +
1748- needed - slicelength ) < 0 )
1698+ needed - slicelength ) < 0 )
17491699 return -1 ;
17501700 memmove (self -> ob_item + (start + needed ) * itemsize ,
17511701 self -> ob_item + stop * itemsize ,
0 commit comments