New submission from Oren Milman <ore...@gmail.com>: The following code: from ctypes import * from _testcapi import PY_SSIZE_T_MAX, LONG_MAX
if LONG_MAX == PY_SSIZE_T_MAX == (1 << 31) - 1: class MyArray(Array): _type_ = c_longlong _length_ = 1 << 29 arr = MyArray() for i in range(3): arr[i] = i for i in range(3): print(arr[i]) Produces this output (on a 32bit Python on my Windows 10): 2 2 2 This is because PyCArrayType_new() (in Modules/_ctypes/_ctypes.c) raises a "array too large" error in case (length * itemsize < 0). However, this multiplication might also overflow to a non-negative number, e.g. to zero in the code above. PyCArrayType_new() then does: stgdict->size = itemsize * length; Array_ass_item() and Array_item() both do: size = stgdict->size / stgdict->length; offset = index * size; So in the above code, the integer overflow caused the array to collapse to a single element (the first element). ISTM that we can fix this by changing the overflow detection logic to this: assert(itemsize >= 0 && length >= 0); array_size = itemsize * length; if (itemsize && array_size / itemsize != length) { PyErr_SetString(PyExc_OverflowError, "array too large"); goto error; } The assertion is guaranteed to be true after #29843 is resolved. (I would open a PR for #29843 soon.) ---------- components: ctypes messages: 303322 nosy: Oren Milman priority: normal severity: normal status: open title: integer overflow in the size of a ctypes.Array type: behavior versions: Python 3.7 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue31637> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com