This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ctypes.Array.from_buffer segmentation fault when trying to create from array.array
Type: crash Stage: resolved
Components: ctypes Versions: Python 3.7, Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: eryksun, martin.panter, python-dev, spearsem@gmail.com, xiang.zhang
Priority: normal Keywords: patch

Created on 2015-11-18 17:57 by spearsem@gmail.com, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
from_buffer.patch martin.panter, 2016-11-19 01:01 review
Pull Requests
URL Status Linked Edit
PR 552 closed dstufft, 2017-03-31 16:36
Messages (4)
msg254851 - (view) Author: Ely Spears (spearsem@gmail.com) Date: 2015-11-18 17:57
I'm trying to find a way to create a ctypes array from the underlying memory buffer exposed by an array.array object. The ctypes.Array.from_buffer function isn't documented, but I did find the source code in _ctypes.c around line 497. It's not clear to me where the problem might be.


Code to reproduce it below:

import array, ctypes
a1 = array.array('l')
a1.fromlist(range(10))
ctypes.Array.from_buffer(a1)
#Segfault
msg254853 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2015-11-18 19:17
You have to subclass ctypes.Array with a _type_ and _length_. But ctypes types also implement sequence repetition (*) to facilitate creating array types. For example:

    import array, ctypes
    a1 = array.array('l')
    a1.fromlist(range(10))
    c1 = (ctypes.c_long * 10).from_buffer(a1)

    >>> c1[:]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> c1[0] = 42
    >>> a1[0]
    42

That said, it's way too easy to segfault this. Why not simply fail the call in this case? e.g.

    StgDictObject *dict = PyType_stgdict(type);
    if (!dict) {
        PyErr_SetString(PyExc_TypeError,
                    "abstract class");
        return NULL;
    }
msg281187 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-11-19 01:01
Here is a patch implementing Eryk’s suggestion, for both from_buffer() and from_buffer_copy() methods. This is exactly how it is already handled for Array.from_address(). The two buffer methods were added more recently than from_address().
msg281309 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-11-20 23:24
New changeset 5f061870d49c by Martin Panter in branch '3.5':
Issue #25659: Change assert to TypeError in from_buffer/_copy()
https://hg.python.org/cpython/rev/5f061870d49c

New changeset 1253ef20c947 by Martin Panter in branch '3.6':
Issue #25659: Merge ctypes fix from 3.5
https://hg.python.org/cpython/rev/1253ef20c947

New changeset 821da4891051 by Martin Panter in branch 'default':
Issue #25659: Merge ctypes fix from 3.6
https://hg.python.org/cpython/rev/821da4891051

New changeset 4de956751cf1 by Martin Panter in branch '2.7':
Issue #25659: Change assert to TypeError in from_buffer/_copy()
https://hg.python.org/cpython/rev/4de956751cf1
History
Date User Action Args
2022-04-11 14:58:23adminsetgithub: 69845
2017-03-31 16:36:26dstufftsetpull_requests: + pull_request1006
2016-11-21 03:32:14martin.pantersetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2016-11-20 23:24:13python-devsetnosy: + python-dev
messages: + msg281309
2016-11-19 01:01:33martin.pantersetfiles: + from_buffer.patch

versions: + Python 3.7, - Python 3.4
keywords: + patch
nosy: + martin.panter

messages: + msg281187
stage: patch review
2015-11-19 04:36:55xiang.zhangsetnosy: + xiang.zhang
2015-11-18 19:17:44eryksunsetnosy: + eryksun

messages: + msg254853
versions: + Python 3.4, Python 3.5, Python 3.6
2015-11-18 17:57:16spearsem@gmail.comcreate