• Richard Hansen's avatar
    work around memoryview.tobytes() off-by-one bug with suboffsets · 78776053
    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>
    
    --HG--
    extra : transplant_source : h%F68%C5f%D2%A9%86%A7o%B4w%27%E5%EDt%3D%D5%3B%3C
    78776053
MemoryView.pyx 46.7 KB