Skip to content

Commit c8cbd28

Browse files
committed
Refactor the array check codes to a function
1 parent fc6f987 commit c8cbd28

File tree

1 file changed

+26
-48
lines changed

1 file changed

+26
-48
lines changed

Modules/arraymodule.c

Lines changed: 26 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,20 @@ Note that the basic Get and Set functions do NOT check that the index is
205205
in 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+
}
221+
208222
static PyObject *
209223
b_getitem(arrayobject *ap, Py_ssize_t i)
210224
{
@@ -222,10 +236,7 @@ b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
222236
if (!PyArg_Parse(v, "h;array item must be integer", &x))
223237
return -1;
224238

225-
// Check buffer validity and bounds after call user-defined method.
226-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
227-
PyErr_SetString(PyExc_IndexError,
228-
"array assignment index out of range");
239+
if (!array_check_bounds_after_user_call(ap, i)) {
229240
return -1;
230241
}
231242

@@ -259,10 +270,7 @@ BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
259270
if (!PyArg_Parse(v, "b;array item must be integer", &x))
260271
return -1;
261272

262-
// Check buffer validity and bounds after call user-defined method.
263-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
264-
PyErr_SetString(PyExc_IndexError,
265-
"array assignment index out of range");
273+
if (!array_check_bounds_after_user_call(ap, i)) {
266274
return -1;
267275
}
268276

@@ -359,10 +367,7 @@ h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
359367
if (!PyArg_Parse(v, "h;array item must be integer", &x))
360368
return -1;
361369

362-
// Check buffer validity and bounds after call user-defined method.
363-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
364-
PyErr_SetString(PyExc_IndexError,
365-
"array assignment index out of range");
370+
if (!array_check_bounds_after_user_call(ap, i)) {
366371
return -1;
367372
}
368373

@@ -396,10 +401,7 @@ HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
396401
return -1;
397402
}
398403

399-
// Check buffer validity and bounds after call user-defined method.
400-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
401-
PyErr_SetString(PyExc_IndexError,
402-
"array assignment index out of range");
404+
if (!array_check_bounds_after_user_call(ap, i)) {
403405
return -1;
404406
}
405407

@@ -422,10 +424,7 @@ i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
422424
if (!PyArg_Parse(v, "i;array item must be integer", &x))
423425
return -1;
424426

425-
// Check buffer validity and bounds after call user-defined method.
426-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
427-
PyErr_SetString(PyExc_IndexError,
428-
"array assignment index out of range");
427+
if (!array_check_bounds_after_user_call(ap, i)) {
429428
return -1;
430429
}
431430

@@ -470,10 +469,7 @@ II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
470469
return -1;
471470
}
472471

473-
// Check buffer validity and bounds after call user-defined method.
474-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
475-
PyErr_SetString(PyExc_IndexError,
476-
"array assignment index out of range");
472+
if (!array_check_bounds_after_user_call(ap, i)) {
477473
if (do_decref) {
478474
Py_DECREF(v);
479475
}
@@ -502,10 +498,7 @@ l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
502498
if (!PyArg_Parse(v, "l;array item must be integer", &x))
503499
return -1;
504500

505-
// Check buffer validity and bounds after call user-defined method.
506-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
507-
PyErr_SetString(PyExc_IndexError,
508-
"array assignment index out of range");
501+
if (!array_check_bounds_after_user_call(ap, i)) {
509502
return -1;
510503
}
511504

@@ -541,10 +534,7 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
541534
return -1;
542535
}
543536

544-
// Check buffer validity and bounds after call user-defined method.
545-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
546-
PyErr_SetString(PyExc_IndexError,
547-
"array assignment index out of range");
537+
if (!array_check_bounds_after_user_call(ap, i)) {
548538
if (do_decref) {
549539
Py_DECREF(v);
550540
}
@@ -573,10 +563,7 @@ q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
573563
if (!PyArg_Parse(v, "L;array item must be integer", &x))
574564
return -1;
575565

576-
// Check buffer validity and bounds after call user-defined method.
577-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
578-
PyErr_SetString(PyExc_IndexError,
579-
"array assignment index out of range");
566+
if (!array_check_bounds_after_user_call(ap, i)) {
580567
return -1;
581568
}
582569

@@ -613,10 +600,7 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
613600
return -1;
614601
}
615602

616-
// Check buffer validity and bounds after call user-defined method.
617-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
618-
PyErr_SetString(PyExc_IndexError,
619-
"array assignment index out of range");
603+
if (!array_check_bounds_after_user_call(ap, i)) {
620604
if (do_decref) {
621605
Py_DECREF(v);
622606
}
@@ -645,10 +629,7 @@ f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
645629
if (!PyArg_Parse(v, "f;array item must be float", &x))
646630
return -1;
647631

648-
// Check buffer validity and bounds after call user-defined method.
649-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
650-
PyErr_SetString(PyExc_IndexError,
651-
"array assignment index out of range");
632+
if (!array_check_bounds_after_user_call(ap, i)) {
652633
return -1;
653634
}
654635

@@ -670,10 +651,7 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
670651
if (!PyArg_Parse(v, "d;array item must be float", &x))
671652
return -1;
672653

673-
// Check buffer validity and bounds after call user-defined method.
674-
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
675-
PyErr_SetString(PyExc_IndexError,
676-
"array assignment index out of range");
654+
if (!array_check_bounds_after_user_call(ap, i)) {
677655
return -1;
678656
}
679657

0 commit comments

Comments
 (0)