Fix crash when calling buffer.request multiple times

buffer.request now creates a temporary Py_buffer instead of a pointer.
This reduces the probability of misstakes, and stops a segfault when
buffer.request was called twice.

Also add build folder to gitignore.
This commit is contained in:
Jonas Adler 2015-12-22 15:18:36 +01:00
parent 1546b85797
commit fc0ca71903
2 changed files with 13 additions and 11 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ cmake_install.cmake
.DS_Store .DS_Store
/example/example.so /example/example.so
/example/example.pyd /example/example.pyd
/build/*
*.sln *.sln
*.sdf *.sdf
*.opensdf *.opensdf

View File

@ -423,20 +423,21 @@ public:
buffer_info request(bool writable = false) { buffer_info request(bool writable = false) {
int flags = PyBUF_STRIDES | PyBUF_FORMAT; int flags = PyBUF_STRIDES | PyBUF_FORMAT;
if (writable) flags |= PyBUF_WRITABLE; if (writable) flags |= PyBUF_WRITABLE;
view = new Py_buffer(); Py_buffer view;
if (PyObject_GetBuffer(m_ptr, view, flags) != 0) if (PyObject_GetBuffer(m_ptr, &view, flags) != 0)
throw error_already_set(); throw error_already_set();
std::vector<size_t> shape(view->ndim), strides(view->ndim); std::vector<size_t> shape(view.ndim), strides(view.ndim);
for (int i=0; i<view->ndim; ++i) { for (int i = 0; i < view.ndim; ++i) {
shape[i] = (size_t) view->shape[i]; shape[i] = (size_t)view.shape[i];
strides[i] = (size_t) view->strides[i]; strides[i] = (size_t)view.strides[i];
} }
return buffer_info(view->buf, view->itemsize, view->format, buffer_info result(view.buf, view.itemsize, view.format,
view->ndim, shape, strides); view.ndim, shape, strides);
PyBuffer_Release(&view);
return result;
} }
~buffer() { if (view) { PyBuffer_Release(view); delete view; } }
private:
Py_buffer *view = nullptr;
}; };
NAMESPACE_BEGIN(detail) NAMESPACE_BEGIN(detail)