@@ -1589,29 +1589,36 @@ array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)
15891589{
15901590 /* Write 64K blocks at a time */
15911591 /* XXX Make the block size settable */
1592- int BLOCKSIZE = 64 * 1024 ;
1593- Py_ssize_t offset = 0 ;
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 ;
1596+ Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1 ) / BLOCKSIZE ;
15941597
15951598 if (Py_SIZE (self ) == 0 )
15961599 goto done ;
15971600
15981601 array_state * state = get_array_state_by_class (cls );
15991602 assert (state != NULL );
16001603
1601- while ( 1 ) {
1604+ for ( Py_ssize_t i = 0 ; i < nblocks ; i ++ ) {
16021605 if (self -> ob_item == NULL || Py_SIZE (self ) == 0 ) {
16031606 break ;
16041607 }
16051608
1606- Py_ssize_t current_nbytes = Py_SIZE (self ) * self -> ob_descr -> itemsize ;
1609+ if (Py_SIZE (self ) > PY_SSIZE_T_MAX / itemsize ) {
1610+ return PyErr_NoMemory ();
1611+ }
16071612
1613+ Py_ssize_t current_nbytes = Py_SIZE (self ) * itemsize ;
1614+ const Py_ssize_t offset = i * BLOCKSIZE ;
16081615 if (offset >= current_nbytes ) {
16091616 break ;
16101617 }
16111618
1612- Py_ssize_t size = BLOCKSIZE ;
1613- if (offset + size > current_nbytes ) {
1614- size = current_nbytes - offset ;
1619+ Py_ssize_t size = current_nbytes - offset ;
1620+ if (size > BLOCKSIZE ) {
1621+ size = BLOCKSIZE ;
16151622 }
16161623
16171624 char * ptr = self -> ob_item + offset ;
@@ -1625,9 +1632,7 @@ array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)
16251632 Py_DECREF (bytes );
16261633 if (res == NULL )
16271634 return NULL ;
1628- Py_DECREF (res );
1629-
1630- offset += size ;
1635+ Py_DECREF (res ); /* drop write result */
16311636 }
16321637
16331638 done :
0 commit comments