From fc0ca719037d54168f9f92d688c700e2ecaaa0c8 Mon Sep 17 00:00:00 2001 From: Jonas Adler Date: Tue, 22 Dec 2015 15:18:36 +0100 Subject: [PATCH] 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. --- .gitignore | 1 + include/pybind11/pytypes.h | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index d8add8ed6..f3c354b01 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ cmake_install.cmake .DS_Store /example/example.so /example/example.pyd +/build/* *.sln *.sdf *.opensdf diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 01776d7eb..d4710519b 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -423,20 +423,21 @@ public: buffer_info request(bool writable = false) { int flags = PyBUF_STRIDES | PyBUF_FORMAT; if (writable) flags |= PyBUF_WRITABLE; - view = new Py_buffer(); - if (PyObject_GetBuffer(m_ptr, view, flags) != 0) + Py_buffer view; + if (PyObject_GetBuffer(m_ptr, &view, flags) != 0) throw error_already_set(); - std::vector shape(view->ndim), strides(view->ndim); - for (int i=0; indim; ++i) { - shape[i] = (size_t) view->shape[i]; - strides[i] = (size_t) view->strides[i]; + std::vector shape(view.ndim), strides(view.ndim); + for (int i = 0; i < view.ndim; ++i) { + shape[i] = (size_t)view.shape[i]; + strides[i] = (size_t)view.strides[i]; } - return buffer_info(view->buf, view->itemsize, view->format, - view->ndim, shape, strides); + buffer_info result(view.buf, view.itemsize, view.format, + 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)