mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Issue #25498: Merge ctypes crash fix from 3.4 into 3.5
This commit is contained in:
commit
0da4ac1f21
4 changed files with 72 additions and 20 deletions
|
@ -463,45 +463,65 @@ KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
|
|||
static PyObject *
|
||||
CDataType_from_buffer(PyObject *type, PyObject *args)
|
||||
{
|
||||
Py_buffer buffer;
|
||||
PyObject *obj;
|
||||
PyObject *mv;
|
||||
PyObject *result;
|
||||
Py_buffer *buffer;
|
||||
Py_ssize_t offset = 0;
|
||||
PyObject *result, *mv;
|
||||
|
||||
StgDictObject *dict = PyType_stgdict(type);
|
||||
assert (dict);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &buffer, &offset))
|
||||
if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset))
|
||||
return NULL;
|
||||
|
||||
mv = PyMemoryView_FromObject(obj);
|
||||
if (mv == NULL)
|
||||
return NULL;
|
||||
|
||||
buffer = PyMemoryView_GET_BUFFER(mv);
|
||||
|
||||
if (buffer->readonly) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"underlying buffer is not writable");
|
||||
Py_DECREF(mv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyBuffer_IsContiguous(buffer, 'C')) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"underlying buffer is not C contiguous");
|
||||
Py_DECREF(mv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"offset cannot be negative");
|
||||
PyBuffer_Release(&buffer);
|
||||
Py_DECREF(mv);
|
||||
return NULL;
|
||||
}
|
||||
if (dict->size > buffer.len - offset) {
|
||||
|
||||
if (dict->size > buffer->len - offset) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Buffer size too small (%zd instead of at least %zd bytes)",
|
||||
buffer.len, dict->size + offset);
|
||||
PyBuffer_Release(&buffer);
|
||||
"Buffer size too small "
|
||||
"(%zd instead of at least %zd bytes)",
|
||||
buffer->len, dict->size + offset);
|
||||
Py_DECREF(mv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = PyCData_AtAddress(type, (char *)buffer.buf + offset);
|
||||
result = PyCData_AtAddress(type, (char *)buffer->buf + offset);
|
||||
if (result == NULL) {
|
||||
PyBuffer_Release(&buffer);
|
||||
Py_DECREF(mv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mv = PyMemoryView_FromBuffer(&buffer);
|
||||
if (mv == NULL) {
|
||||
PyBuffer_Release(&buffer);
|
||||
if (-1 == KeepRef((CDataObject *)result, -1, mv)) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
/* Hack the memoryview so that it will release the buffer. */
|
||||
((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj;
|
||||
((PyMemoryViewObject *)mv)->view.obj = buffer.obj;
|
||||
if (-1 == KeepRef((CDataObject *)result, -1, mv))
|
||||
result = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue