• Richard Hansen's avatar
    work around memoryview.tobytes() off-by-one bug with suboffsets · 1a82d8bb
    Richard Hansen authored
    In CPython 2.7, the memoryview.tobytes() method (implemented in
    function memoryview_tobytes() in cpython/Objects/memoryobject.c) calls
    PyBuffer_ToContiguous() to copy the bytes in the buffer object to the
    newly allocated string memory.  PyBuffer_ToContiguous() in turn calls
    PyBuffer_IsContiguous(), which always returns false when the
    suboffsets member of the Py_buffer struct is non-NULL (even if all
    entries in that array are negative!).  When PyBuffer_IsContiguous()
    returns false, PyBuffer_ToContiguous() runs an alternative memory copy
    scheme which apparently has an off-by-one bug that the normal memory
    copy scheme doesn't have.
    
    This change sets the Py_buffer suboffsets member to NULL if all
    entries are negative, avoiding the off-by-one bug.
    
    To reproduce the bug:
    
        cpdef foo():
            cdef unsigned char[:] v = bytearray("testing")
            # the following prints 'estingt' without this workaround
            print repr(memoryview(v).tobytes())
    Signed-off-by: default avatarRichard Hansen <rhansen@bbn.com>
    1a82d8bb
MemoryView.pyx 46.7 KB