[NumPy-Tickets] [NumPy] #2151: flatiter does not work correctly with non-writeable arrays
NumPy Trac
numpy-tickets@scipy....
Tue Jun 5 21:45:42 CDT 2012
#2151: flatiter does not work correctly with non-writeable arrays
------------------------+---------------------------------------------------
Reporter: tux | Owner: somebody
Type: defect | Status: new
Priority: normal | Milestone: Unscheduled
Component: numpy.core | Version: 1.6.1
Keywords: |
------------------------+---------------------------------------------------
I found out that numpy.flatiter objects do not retain the base object's
writeable flag. While this only leads to unexpected behavior for normal
non-writeable arrays, this causes a segfault if the array's buffer is a
read-only memory area (e.g. mmap).
crashme1.py shows one part of the problem. The array b is created with the
mmaped array a as its base. The current code creates a copy and sets the
UPDATEIFCOPY flag if a is not C_CONTIGUOUS (I used Fortran order here).
Now when b is destroyed it tries to write to its base (UPDATEIFCOPY) which
causes a segfault because the buffer is a read-only mmap.
I tried to fix this problem by only setting updateifcopy only if the
original array is writeable. If not, the flatiter should be non-writeable
as well in my opinion to prevent people from trying to change the original
array with it which would not work. I'm not perfectly sure that I got the
semantics of iter_array(iterators.c) right. Somebody with more insight
into numpy should judge. At least the comment of iter_array should also be
updated to reflect the new situation.
After I implemented this, stumbled on another bug. Even if the flatiter is
non-writeable, the function array_flat_set(getset.c) does not actually
check the flag before writing to the array. This is demonstrated in the
example write_the_unwriteable.py. If the non-writeable array is a read-
only memory area, we get a segfault again (see crashme2.py).
To fix this I added a check for the writeable flag at the beginning of
array_flat_set which throws an appropriate exception (the same that direct
assignment would cause).
I tested all of the above on Debian Sid (Python 2.7.3 and numpy 1.6.2),
Ubuntu Precise (Python 2.7.3 and numpy 1.6.1) and a self-compiled version
of Python 2.7.1 and numpy 1.6.1. I could also reproduce it with python
3.2.
I attached my patches against the current git HEAD to this report.
--
Ticket URL: <http://projects.scipy.org/numpy/ticket/2151>
NumPy <http://projects.scipy.org/numpy>
My example project
More information about the NumPy-Tickets
mailing list