Skip to content

Commit 67e98b5

Browse files
committed
Also check if the ob_item's size is changed by user's code
1 parent e3c728a commit 67e98b5

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

Lib/test/test_array.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,19 @@ def __index__(self):
16971697

16981698
self.assertEqual(len(victim), 0)
16991699

1700+
# Test case where array is shrunk but not completely cleared
1701+
victim2 = array.array('b', [1, 2, 3])
1702+
1703+
class ShrinkIndex:
1704+
def __index__(self):
1705+
# Pop two elements, making array size 1, so index 1 is out of bounds
1706+
victim2.pop()
1707+
victim2.pop()
1708+
return 0
1709+
1710+
with self.assertRaises(IndexError):
1711+
victim2[1] = ShrinkIndex()
1712+
17001713

17011714
if __name__ == "__main__":
17021715
unittest.main()

Modules/arraymodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
222222
if (!PyArg_Parse(v, "h;array item must be integer", &x))
223223
return -1;
224224

225-
/* Check buffer validity after PyArg_Parse which may call user-defined
225+
/* Check buffer validity and bounds after PyArg_Parse which may call user-defined
226226
* __index__ on v, which might modify the array buffer. See gh-142555.
227227
*/
228-
if (i >= 0 && ap->ob_item == NULL) {
228+
if (i >= 0 && (ap->ob_item == NULL || i >= Py_SIZE(ap))) {
229229
PyErr_SetString(PyExc_IndexError,
230230
"array assignment index out of range");
231231
return -1;

0 commit comments

Comments
 (0)