@@ -1587,35 +1587,52 @@ static PyObject *
15871587array_array_tofile_impl (arrayobject * self , PyTypeObject * cls , PyObject * f )
15881588/*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52]*/
15891589{
1590- Py_ssize_t nbytes = Py_SIZE (self ) * self -> ob_descr -> itemsize ;
15911590 /* Write 64K blocks at a time */
15921591 /* XXX Make the block size settable */
1593- int BLOCKSIZE = 64 * 1024 ;
1592+ const Py_ssize_t BLOCKSIZE = 64 * 1024 ;
1593+ const Py_ssize_t itemsize = self -> ob_descr -> itemsize ;
1594+
1595+ Py_ssize_t nbytes = Py_SIZE (self ) * itemsize ;
15941596 Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1 ) / BLOCKSIZE ;
1595- Py_ssize_t i ;
15961597
15971598 if (Py_SIZE (self ) == 0 )
15981599 goto done ;
15991600
1600-
16011601 array_state * state = get_array_state_by_class (cls );
16021602 assert (state != NULL );
16031603
1604- for (i = 0 ; i < nblocks ; i ++ ) {
1605- char * ptr = self -> ob_item + i * BLOCKSIZE ;
1606- Py_ssize_t size = BLOCKSIZE ;
1604+ for (Py_ssize_t i = 0 ; i < nblocks ; i ++ ) {
1605+ if (self -> ob_item == NULL || Py_SIZE (self ) == 0 ) {
1606+ break ;
1607+ }
1608+
1609+ if (Py_SIZE (self ) > PY_SSIZE_T_MAX / itemsize ) {
1610+ return PyErr_NoMemory ();
1611+ }
1612+
1613+ Py_ssize_t current_nbytes = Py_SIZE (self ) * itemsize ;
1614+ const Py_ssize_t offset = i * BLOCKSIZE ;
1615+ if (offset >= current_nbytes ) {
1616+ break ;
1617+ }
1618+
1619+ Py_ssize_t size = current_nbytes - offset ;
1620+ if (size > BLOCKSIZE ) {
1621+ size = BLOCKSIZE ;
1622+ }
1623+
1624+ char * ptr = self -> ob_item + offset ;
16071625 PyObject * bytes , * res ;
16081626
1609- if (i * BLOCKSIZE + size > nbytes )
1610- size = nbytes - i * BLOCKSIZE ;
16111627 bytes = PyBytes_FromStringAndSize (ptr , size );
16121628 if (bytes == NULL )
16131629 return NULL ;
1630+
16141631 res = PyObject_CallMethodOneArg (f , state -> str_write , bytes );
16151632 Py_DECREF (bytes );
16161633 if (res == NULL )
16171634 return NULL ;
1618- Py_DECREF (res ); /* drop write result */
1635+ Py_DECREF (res );
16191636 }
16201637
16211638 done :
0 commit comments