Commit 06c0c96b authored by Mark Florisson's avatar Mark Florisson

Fix segfault caused by NULL suboffsets

parent f5134ba8
......@@ -471,15 +471,19 @@ def assign_scalar(dst, scalar, code):
code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, dst.result()))
dst_temp = "__pyx_temp_slice"
with slice_iter(dst.type, dst_temp, dst.type.ndim, code) as p:
if dtype.is_pyobject:
code.putln("Py_DECREF((PyObject *) %s);" % p)
# with slice_iter(dst.type, dst_temp, dst.type.ndim, code) as p:
slice_iter_obj = slice_iter(dst.type, dst_temp, dst.type.ndim, code)
p = slice_iter_obj.start_loops()
code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
if dtype.is_pyobject:
code.putln("Py_DECREF((PyObject *) %s);" % p)
if dtype.is_pyobject:
code.putln("Py_INCREF(__pyx_temp_scalar);")
code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
if dtype.is_pyobject:
code.putln("Py_INCREF(__pyx_temp_scalar);")
slice_iter_obj.end_loops()
code.end_block()
def slice_iter(slice_type, slice_temp, ndim, code):
......@@ -496,7 +500,7 @@ class SliceIter(object):
self.ndim = ndim
class ContigSliceIter(SliceIter):
def __enter__(self):
def start_loops(self):
code = self.code
code.begin_block()
......@@ -514,13 +518,13 @@ class ContigSliceIter(SliceIter):
return "__pyx_temp_pointer"
def __exit__(self, *args):
def end_loops(self):
self.code.putln("__pyx_temp_pointer += 1;")
self.code.putln("}")
self.code.end_block()
class StridedSliceIter(SliceIter):
def __enter__(self):
def start_loops(self):
code = self.code
code.begin_block()
......@@ -543,7 +547,7 @@ class StridedSliceIter(SliceIter):
return "__pyx_temp_pointer_%d" % (self.ndim - 1)
def __exit__(self, *args):
def end_loops(self):
code = self.code
for i in range(self.ndim - 1, -1, -1):
code.putln("__pyx_temp_pointer_%d += __pyx_temp_stride_%d;" % (i, i))
......
......@@ -403,7 +403,8 @@ cdef class memoryview(object):
# It would be easy to support indirect dimensions, but it's easier
# to disallow :)
assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
if self.view.suboffsets != NULL:
assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
slice_assign_scalar(dst_slice, self.view.ndim, self.view.itemsize,
item, self.dtype_is_object)
free(tmp)
......@@ -973,14 +974,22 @@ cdef {{memviewslice_name}} *get_slice_from_memview(memoryview memview,
@cname('__pyx_memoryview_slice_copy')
cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst):
cdef int dim
cdef Py_ssize_t *shape, *strides, *suboffsets
shape = memview.view.shape
strides = memview.view.strides
suboffsets = memview.view.suboffsets
dst.memview = <__pyx_memoryview *> memview
dst.data = <char *> memview.view.buf
for dim in range(memview.view.ndim):
dst.shape[dim] = memview.view.shape[dim]
dst.strides[dim] = memview.view.strides[dim]
dst.suboffsets[dim] = memview.view.suboffsets[dim]
dst.shape[dim] = shape[dim]
dst.strides[dim] = strides[dim]
if suboffsets == NULL:
dst.suboffsets[dim] = -1
else:
dst.suboffsets[dim] = suboffsets[dim]
@cname('__pyx_memoryview_copy_object')
cdef memoryview_copy(memoryview memview):
......
......@@ -189,20 +189,23 @@ def test_transpose():
print a[3, 2], a.T[2, 3], a_obj[3, 2], a_obj.T[2, 3], numpy_obj[3, 2], numpy_obj.T[2, 3]
@testcase
@testcase_numpy_1_5
def test_numpy_like_attributes(cyarray):
"""
For some reason this fails in numpy 1.4, with shape () and strides (40, 8)
instead of 20, 4 on my machine. Investigate this.
>>> cyarray = create_array(shape=(8, 5), mode="c")
>>> test_numpy_like_attributes(cyarray)
>>> test_numpy_like_attributes(cyarray.memview)
"""
numarray = np.asarray(cyarray)
assert cyarray.shape == numarray.shape
assert cyarray.strides == numarray.strides
assert cyarray.ndim == numarray.ndim
assert cyarray.size == numarray.size
assert cyarray.nbytes == numarray.nbytes
assert cyarray.shape == numarray.shape, (cyarray.shape, numarray.shape)
assert cyarray.strides == numarray.strides, (cyarray.strides, numarray.strides)
assert cyarray.ndim == numarray.ndim, (cyarray.ndim, numarray.ndim)
assert cyarray.size == numarray.size, (cyarray.size, numarray.size)
assert cyarray.nbytes == numarray.nbytes, (cyarray.nbytes, numarray.nbytes)
cdef int[:, :] mslice = numarray
assert (<object> mslice).base is numarray
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment