@@ -205,19 +205,28 @@ Note that the basic Get and Set functions do NOT check that the index is
205205in bounds; that's the responsibility of the caller.
206206****************************************************************************/
207207
208- /* Check array buffer validity and bounds after calling user-defined methods
209- (like __index__ or __float__) that might modify the array during the call.
210- Returns false on error, true on success. */
211- static inline bool
212- array_check_bounds_after_user_call (arrayobject * ap , Py_ssize_t i )
213- {
214- if (i >= 0 && (ap -> ob_item == NULL || i >= Py_SIZE (ap ))) {
215- PyErr_SetString (PyExc_IndexError ,
216- "array assignment index out of range" );
217- return false;
218- }
219- return true;
220- }
208+ /* Macro to check array buffer validity and bounds after calling
209+ user-defined methods (like __index__ or __float__) that might modify
210+ the array during the call.
211+ */
212+ #define CHECK_ARRAY_BOUNDS (ap , i ) \
213+ do { \
214+ if ((i) >= 0 && ((ap)->ob_item == NULL || (i) >= Py_SIZE((ap)))) { \
215+ PyErr_SetString(PyExc_IndexError, "array assignment index out of range"); \
216+ return -1; \
217+ } \
218+ } while (0)
219+
220+ #define CHECK_ARRAY_BOUNDS_WITH_CLEANUP (ap , i , v , cleanup ) \
221+ do { \
222+ if ((i) >= 0 && ((ap)->ob_item == NULL || (i) >= Py_SIZE((ap)))) { \
223+ PyErr_SetString(PyExc_IndexError, "array assignment index out of range"); \
224+ if (cleanup) { \
225+ Py_DECREF(v); \
226+ } \
227+ return -1; \
228+ } \
229+ } while (0)
221230
222231static PyObject *
223232b_getitem (arrayobject * ap , Py_ssize_t i )
@@ -236,9 +245,7 @@ b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
236245 if (!PyArg_Parse (v , "h;array item must be integer" , & x ))
237246 return -1 ;
238247
239- if (!array_check_bounds_after_user_call (ap , i )) {
240- return -1 ;
241- }
248+ CHECK_ARRAY_BOUNDS (ap , i );
242249
243250 if (x < -128 ) {
244251 PyErr_SetString (PyExc_OverflowError ,
@@ -270,9 +277,7 @@ BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
270277 if (!PyArg_Parse (v , "b;array item must be integer" , & x ))
271278 return -1 ;
272279
273- if (!array_check_bounds_after_user_call (ap , i )) {
274- return -1 ;
275- }
280+ CHECK_ARRAY_BOUNDS (ap , i );
276281
277282 if (i >= 0 )
278283 ((unsigned char * )ap -> ob_item )[i ] = x ;
@@ -367,9 +372,7 @@ h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
367372 if (!PyArg_Parse (v , "h;array item must be integer" , & x ))
368373 return -1 ;
369374
370- if (!array_check_bounds_after_user_call (ap , i )) {
371- return -1 ;
372- }
375+ CHECK_ARRAY_BOUNDS (ap , i );
373376
374377 if (i >= 0 )
375378 ((short * )ap -> ob_item )[i ] = x ;
@@ -401,9 +404,7 @@ HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
401404 return -1 ;
402405 }
403406
404- if (!array_check_bounds_after_user_call (ap , i )) {
405- return -1 ;
406- }
407+ CHECK_ARRAY_BOUNDS (ap , i );
407408
408409 if (i >= 0 )
409410 ((short * )ap -> ob_item )[i ] = (short )x ;
@@ -424,9 +425,7 @@ i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
424425 if (!PyArg_Parse (v , "i;array item must be integer" , & x ))
425426 return -1 ;
426427
427- if (!array_check_bounds_after_user_call (ap , i )) {
428- return -1 ;
429- }
428+ CHECK_ARRAY_BOUNDS (ap , i );
430429
431430 if (i >= 0 )
432431 ((int * )ap -> ob_item )[i ] = x ;
@@ -469,12 +468,7 @@ II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
469468 return -1 ;
470469 }
471470
472- if (!array_check_bounds_after_user_call (ap , i )) {
473- if (do_decref ) {
474- Py_DECREF (v );
475- }
476- return -1 ;
477- }
471+ CHECK_ARRAY_BOUNDS_WITH_CLEANUP (ap , i , v , do_decref );
478472
479473 if (i >= 0 )
480474 ((unsigned int * )ap -> ob_item )[i ] = (unsigned int )x ;
@@ -498,9 +492,7 @@ l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
498492 if (!PyArg_Parse (v , "l;array item must be integer" , & x ))
499493 return -1 ;
500494
501- if (!array_check_bounds_after_user_call (ap , i )) {
502- return -1 ;
503- }
495+ CHECK_ARRAY_BOUNDS (ap , i );
504496
505497 if (i >= 0 )
506498 ((long * )ap -> ob_item )[i ] = x ;
@@ -534,12 +526,7 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
534526 return -1 ;
535527 }
536528
537- if (!array_check_bounds_after_user_call (ap , i )) {
538- if (do_decref ) {
539- Py_DECREF (v );
540- }
541- return -1 ;
542- }
529+ CHECK_ARRAY_BOUNDS_WITH_CLEANUP (ap , i , v , do_decref );
543530
544531 if (i >= 0 )
545532 ((unsigned long * )ap -> ob_item )[i ] = x ;
@@ -563,9 +550,7 @@ q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
563550 if (!PyArg_Parse (v , "L;array item must be integer" , & x ))
564551 return -1 ;
565552
566- if (!array_check_bounds_after_user_call (ap , i )) {
567- return -1 ;
568- }
553+ CHECK_ARRAY_BOUNDS (ap , i );
569554
570555 if (i >= 0 )
571556 ((long long * )ap -> ob_item )[i ] = x ;
@@ -600,12 +585,7 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
600585 return -1 ;
601586 }
602587
603- if (!array_check_bounds_after_user_call (ap , i )) {
604- if (do_decref ) {
605- Py_DECREF (v );
606- }
607- return -1 ;
608- }
588+ CHECK_ARRAY_BOUNDS_WITH_CLEANUP (ap , i , v , do_decref );
609589
610590 if (i >= 0 )
611591 ((unsigned long long * )ap -> ob_item )[i ] = x ;
@@ -629,9 +609,7 @@ f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
629609 if (!PyArg_Parse (v , "f;array item must be float" , & x ))
630610 return -1 ;
631611
632- if (!array_check_bounds_after_user_call (ap , i )) {
633- return -1 ;
634- }
612+ CHECK_ARRAY_BOUNDS (ap , i );
635613
636614 if (i >= 0 )
637615 ((float * )ap -> ob_item )[i ] = x ;
@@ -651,9 +629,7 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
651629 if (!PyArg_Parse (v , "d;array item must be float" , & x ))
652630 return -1 ;
653631
654- if (!array_check_bounds_after_user_call (ap , i )) {
655- return -1 ;
656- }
632+ CHECK_ARRAY_BOUNDS (ap , i );
657633
658634 if (i >= 0 )
659635 ((double * )ap -> ob_item )[i ] = x ;
0 commit comments