diff options
Diffstat (limited to 'Modules/_ctypes/_ctypes.c')
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index fabbdf13e9..9b289af91b 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1460,24 +1460,36 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyTypeObject *result; StgDictObject *stgdict; StgDictObject *itemdict; - PyObject *proto; + PyObject *proto, *length_attr; PyObject *typedict; - long length; - + Py_ssize_t length; Py_ssize_t itemsize, itemalign; typedict = PyTuple_GetItem(args, 2); if (!typedict) return NULL; - proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */ - if (!proto || !PyInt_Check(proto)) { + length_attr = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */ + if (!length_attr || !_PyAnyInt_Check(length_attr)) { PyErr_SetString(PyExc_AttributeError, "class must define a '_length_' attribute, " "which must be a positive integer"); return NULL; } - length = PyInt_AS_LONG(proto); + if (PyInt_Check(length_attr)) { + length = PyInt_AS_LONG(length_attr); + } + else { + assert(PyLong_Check(length_attr)); + length = PyLong_AsSsize_t(length_attr); + if (length == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "The '_length_' attribute is too large"); + } + return NULL; + } + } proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ if (!proto) { |