Skip to content

Commit a10f717

Browse files
orenmntaleinat
authored andcommitted
same as draft 2 in bpo, except for a small change to the test
1 parent a323cdc commit a10f717

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

Lib/ctypes/test/test_arrays.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,24 @@ class T(Array):
183183
_type_ = c_int
184184
_length_ = 1.87
185185

186+
def test_bad_length(self):
187+
with self.assertRaises(ValueError):
188+
class T(Array):
189+
_type_ = c_int
190+
_length_ = -1 << 1000
191+
with self.assertRaises(ValueError):
192+
class T(Array):
193+
_type_ = c_int
194+
_length_ = -1
195+
with self.assertRaises(OverflowError):
196+
class T(Array):
197+
_type_ = c_int
198+
_length_ = 1 << 1000
199+
# _length_ might be zero.
200+
class T(Array):
201+
_type_ = c_int
202+
_length_ = 0
203+
186204
@unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
187205
@bigmemtest(size=_2G, memuse=1, dry_run=False)
188206
def test_large_array(self, size):

Modules/_ctypes/_ctypes.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
13911391
StgDictObject *itemdict;
13921392
PyObject *length_attr, *type_attr;
13931393
Py_ssize_t length;
1394+
int overflow;
13941395
Py_ssize_t itemsize, itemalign;
13951396

13961397
/* create the new instance (which is a class,
@@ -1412,13 +1413,21 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14121413
Py_XDECREF(length_attr);
14131414
goto error;
14141415
}
1415-
length = PyLong_AsSsize_t(length_attr);
1416+
length = PyLong_AsLongAndOverflow(length_attr, &overflow);
14161417
Py_DECREF(length_attr);
1417-
if (length == -1 && PyErr_Occurred()) {
1418-
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1418+
/* PyLong_Check(length_attr) is true, so it is guaranteed that
1419+
no error occurred in PyLong_AsLongAndOverflow(). */
1420+
assert(!(length == -1 && PyErr_Occurred()));
1421+
if (overflow || length < 0) {
1422+
if (overflow > 0) {
14191423
PyErr_SetString(PyExc_OverflowError,
14201424
"The '_length_' attribute is too large");
14211425
}
1426+
else {
1427+
assert(overflow < 0 || length < 0);
1428+
PyErr_SetString(PyExc_ValueError,
1429+
"The '_length_' attribute must be non-negative");
1430+
}
14221431
goto error;
14231432
}
14241433

0 commit comments

Comments
 (0)