@@ -154,7 +154,8 @@ enum machine_format_code {
154154static  inline  bool 
155155arraydata_size_valid (Py_ssize_t  size , int  itemsize )
156156{
157-     return  size  <= (PY_SSIZE_T_MAX  -  (Py_ssize_t )sizeof (arraydata )) / itemsize ;
157+     return  size  >= 0  && 
158+         size  <= (PY_SSIZE_T_MAX  -  (Py_ssize_t )sizeof (arraydata )) / itemsize ;
158159}
159160
160161static  arraydata  * 
@@ -213,6 +214,7 @@ static int
213214array_resize (arrayobject  * self , Py_ssize_t  newsize )
214215{
215216    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
217+     assert (newsize  >= 0 );
216218
217219    if  (self -> ob_exports  >  0  &&  newsize  !=  Py_SIZE (self )) {
218220        PyErr_SetString (PyExc_BufferError ,
@@ -267,6 +269,11 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
267269     */ 
268270
269271    size_t  _new_size  =  (newsize  >> 4 ) +  (Py_SIZE (self ) <  8  ? 3  : 7 ) +  newsize ;
272+     // Limit over-allocation to not overflow Py_ssize_t, newsize can't ever be 
273+     // larger than this anyway. 
274+     if  (_new_size  >  PY_SSIZE_T_MAX ) {
275+         _new_size  =  PY_SSIZE_T_MAX ;
276+     }
270277    int  itemsize  =  self -> ob_descr -> itemsize ;
271278
272279    if  (!arraydata_size_valid (_new_size , itemsize )) {
@@ -2116,7 +2123,13 @@ array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
21162123        if  (ustr_length  >  1 ) {
21172124            ustr_length -- ; /* trim trailing NUL character */ 
21182125            Py_ssize_t  old_size  =  Py_SIZE (self );
2119-             if  (array_resize (self , old_size  +  ustr_length ) ==  -1 ) {
2126+             // if overflows PY_SSIZE_T_MAX arraydata_size_valid() will catch it 
2127+             Py_ssize_t  new_size  =  old_size  +  ustr_length ;
2128+ 
2129+             if  (!arraydata_size_valid (new_size , sizeof (wchar_t ))) {
2130+                 return  PyErr_NoMemory ();
2131+             }
2132+             if  (array_resize (self , new_size ) ==  -1 ) {
21202133                return  NULL ;
21212134            }
21222135
@@ -2128,9 +2141,10 @@ array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
21282141    else  { // typecode == 'w' 
21292142        Py_ssize_t  ustr_length  =  PyUnicode_GetLength (ustr );
21302143        Py_ssize_t  old_size  =  Py_SIZE (self );
2144+         // if overflows PY_SSIZE_T_MAX arraydata_size_valid() will catch it 
21312145        Py_ssize_t  new_size  =  old_size  +  ustr_length ;
21322146
2133-         if  (new_size   <   0   ||   !arraydata_size_valid (new_size , sizeof (Py_UCS4 ))) {
2147+         if  (!arraydata_size_valid (new_size , sizeof (Py_UCS4 ))) {
21342148            return  PyErr_NoMemory ();
21352149        }
21362150        if  (array_resize (self , new_size ) ==  -1 ) {
0 commit comments