Patch #1521817: The index range checking on ctypes arrays containing
exactly one element is enabled again.
This commit is contained in:
parent
9f902470da
commit
ce049a0aef
|
@ -46,70 +46,5 @@ class VarSizeTest(unittest.TestCase):
|
||||||
self.failUnlessRaises(IndexError, array.__setitem__, -1, None)
|
self.failUnlessRaises(IndexError, array.__setitem__, -1, None)
|
||||||
self.failUnlessRaises(IndexError, array.__getitem__, -1)
|
self.failUnlessRaises(IndexError, array.__getitem__, -1)
|
||||||
|
|
||||||
def test_varsized_array(self):
|
|
||||||
array = (c_int * 20)(20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
|
|
||||||
|
|
||||||
# no range checking is done on arrays with size == 1
|
|
||||||
varsize_array = (c_int * 1).from_address(addressof(array))
|
|
||||||
|
|
||||||
# __getitem__
|
|
||||||
self.failUnlessEqual(varsize_array[0], 20)
|
|
||||||
self.failUnlessEqual(varsize_array[1], 21)
|
|
||||||
self.failUnlessEqual(varsize_array[2], 22)
|
|
||||||
self.failUnlessEqual(varsize_array[3], 23)
|
|
||||||
self.failUnlessEqual(varsize_array[4], 24)
|
|
||||||
self.failUnlessEqual(varsize_array[5], 25)
|
|
||||||
self.failUnlessEqual(varsize_array[6], 26)
|
|
||||||
self.failUnlessEqual(varsize_array[7], 27)
|
|
||||||
self.failUnlessEqual(varsize_array[8], 28)
|
|
||||||
self.failUnlessEqual(varsize_array[9], 29)
|
|
||||||
|
|
||||||
# still, normal sequence of length one behaviour:
|
|
||||||
self.failUnlessEqual(varsize_array[-1], 20)
|
|
||||||
self.failUnlessRaises(IndexError, lambda: varsize_array[-2])
|
|
||||||
# except for this one, which will raise MemoryError
|
|
||||||
self.failUnlessRaises(MemoryError, lambda: varsize_array[:])
|
|
||||||
|
|
||||||
# __setitem__
|
|
||||||
varsize_array[0] = 100
|
|
||||||
varsize_array[1] = 101
|
|
||||||
varsize_array[2] = 102
|
|
||||||
varsize_array[3] = 103
|
|
||||||
varsize_array[4] = 104
|
|
||||||
varsize_array[5] = 105
|
|
||||||
varsize_array[6] = 106
|
|
||||||
varsize_array[7] = 107
|
|
||||||
varsize_array[8] = 108
|
|
||||||
varsize_array[9] = 109
|
|
||||||
|
|
||||||
for i in range(10):
|
|
||||||
self.failUnlessEqual(varsize_array[i], i + 100)
|
|
||||||
self.failUnlessEqual(array[i], i + 100)
|
|
||||||
|
|
||||||
# __getslice__
|
|
||||||
self.failUnlessEqual(varsize_array[0:10], range(100, 110))
|
|
||||||
self.failUnlessEqual(varsize_array[1:9], range(101, 109))
|
|
||||||
self.failUnlessEqual(varsize_array[1:-1], [])
|
|
||||||
|
|
||||||
# __setslice__
|
|
||||||
varsize_array[0:10] = range(1000, 1010)
|
|
||||||
self.failUnlessEqual(varsize_array[0:10], range(1000, 1010))
|
|
||||||
|
|
||||||
varsize_array[1:9] = range(1001, 1009)
|
|
||||||
self.failUnlessEqual(varsize_array[1:9], range(1001, 1009))
|
|
||||||
|
|
||||||
def test_vararray_is_sane(self):
|
|
||||||
array = (c_int * 15)(20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
|
|
||||||
|
|
||||||
varsize_array = (c_int * 1).from_address(addressof(array))
|
|
||||||
varsize_array[:] = [1, 2, 3, 4, 5]
|
|
||||||
|
|
||||||
self.failUnlessEqual(array[:], [1, 2, 3, 4, 5, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0])
|
|
||||||
self.failUnlessEqual(varsize_array[0:10], [1, 2, 3, 4, 5, 25, 26, 27, 28, 29])
|
|
||||||
|
|
||||||
array[:5] = [10, 11, 12, 13, 14]
|
|
||||||
self.failUnlessEqual(array[:], [10, 11, 12, 13, 14, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0])
|
|
||||||
self.failUnlessEqual(varsize_array[0:10], [10, 11, 12, 13, 14, 25, 26, 27, 28, 29])
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -25,6 +25,10 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Patch #1521817: Index range checking on ctypes arrays containing
|
||||||
|
exactly one element enabled again. This allows iterating over these
|
||||||
|
arrays, without the need to check the array size before.
|
||||||
|
|
||||||
- Bug #1521375: When the code in ctypes.util.find_library was
|
- Bug #1521375: When the code in ctypes.util.find_library was
|
||||||
run with root privileges, it could overwrite or delete
|
run with root privileges, it could overwrite or delete
|
||||||
/dev/null in certain cases; this is now fixed.
|
/dev/null in certain cases; this is now fixed.
|
||||||
|
|
|
@ -3573,7 +3573,8 @@ Array_item(PyObject *_self, Py_ssize_t index)
|
||||||
int offset, size;
|
int offset, size;
|
||||||
StgDictObject *stgdict;
|
StgDictObject *stgdict;
|
||||||
|
|
||||||
if (self->b_length == 0 || index < 0 || (self->b_length > 1 && index >= self->b_length)) {
|
|
||||||
|
if (index < 0 || index >= self->b_length) {
|
||||||
PyErr_SetString(PyExc_IndexError,
|
PyErr_SetString(PyExc_IndexError,
|
||||||
"invalid index");
|
"invalid index");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3602,11 +3603,11 @@ Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||||
|
|
||||||
if (ilow < 0)
|
if (ilow < 0)
|
||||||
ilow = 0;
|
ilow = 0;
|
||||||
else if (ilow > self->b_length && self->b_length != 1)
|
else if (ilow > self->b_length)
|
||||||
ilow = self->b_length;
|
ilow = self->b_length;
|
||||||
if (ihigh < ilow)
|
if (ihigh < ilow)
|
||||||
ihigh = ilow;
|
ihigh = ilow;
|
||||||
else if (ihigh > self->b_length && self->b_length != 1)
|
else if (ihigh > self->b_length)
|
||||||
ihigh = self->b_length;
|
ihigh = self->b_length;
|
||||||
len = ihigh - ilow;
|
len = ihigh - ilow;
|
||||||
|
|
||||||
|
@ -3649,8 +3650,7 @@ Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
|
||||||
}
|
}
|
||||||
|
|
||||||
stgdict = PyObject_stgdict((PyObject *)self);
|
stgdict = PyObject_stgdict((PyObject *)self);
|
||||||
if (self->b_length == 0 || index < 0
|
if (index < 0 || index >= stgdict->length) {
|
||||||
|| (self->b_length > 1 && index >= self->b_length)) {
|
|
||||||
PyErr_SetString(PyExc_IndexError,
|
PyErr_SetString(PyExc_IndexError,
|
||||||
"invalid index");
|
"invalid index");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -3677,19 +3677,17 @@ Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *va
|
||||||
|
|
||||||
if (ilow < 0)
|
if (ilow < 0)
|
||||||
ilow = 0;
|
ilow = 0;
|
||||||
else if (ilow > self->b_length && self->b_length != 1)
|
else if (ilow > self->b_length)
|
||||||
ilow = self->b_length;
|
ilow = self->b_length;
|
||||||
|
|
||||||
if (ihigh < 0)
|
if (ihigh < 0)
|
||||||
ihigh = 0;
|
ihigh = 0;
|
||||||
|
|
||||||
if (ihigh < ilow)
|
if (ihigh < ilow)
|
||||||
ihigh = ilow;
|
ihigh = ilow;
|
||||||
else if (ihigh > self->b_length && self->b_length != 1)
|
else if (ihigh > self->b_length)
|
||||||
ihigh = self->b_length;
|
ihigh = self->b_length;
|
||||||
|
|
||||||
len = PySequence_Length(value);
|
len = PySequence_Length(value);
|
||||||
if (self->b_length != 1 && len != ihigh - ilow) {
|
if (len != ihigh - ilow) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Can only assign sequence of same size");
|
"Can only assign sequence of same size");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue