diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-05-11 15:48:11 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-05-14 11:45:41 +0200 |
commit | 2641a665fbcf1d0326bde6e4f610e775881f8430 (patch) | |
tree | 50222fe86d2d652df80a15719eb11fbe5cc9cc2b /sources | |
parent | 967be4ead8781da67b71b177d124764de5fd0aa3 (diff) |
Fix crashes when using the QImage(uchar *) data constructors
The constructors expect a range of memory that remains valid
through the lifetime of the image and may also modify it.
Crashes occurred since apparently the Py_Buffer was released before
it.
To fix this, add a new buffer helper, copyData() that makes a copy
of the data and pass that along with std::free() as cleanup
function.
Fixes: PYSIDE-1563
Change-Id: Idb09eadea658f02968f75c6bdfc6cc3f467111d5
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit cc011c8980cc4ce02e3d9cceb74ee028c204214e)
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
-rw-r--r-- | sources/pyside2/PySide2/templates/gui_common.xml | 4 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/shibokenbuffer.cpp | 23 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/shibokenbuffer.h | 8 |
3 files changed, 33 insertions, 2 deletions
diff --git a/sources/pyside2/PySide2/templates/gui_common.xml b/sources/pyside2/PySide2/templates/gui_common.xml index a139a5fe9..16116877f 100644 --- a/sources/pyside2/PySide2/templates/gui_common.xml +++ b/sources/pyside2/PySide2/templates/gui_common.xml @@ -80,8 +80,8 @@ </template> <template name="qimage_buffer_constructor"> - auto ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1)); - %0 = new %TYPE(ptr, %ARGS); + auto *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::copyData(%PYARG_1)); + %0 = new %TYPE(ptr, %ARGS, std::free); </template> <template name="qcolor_repr"> diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.cpp b/sources/shiboken2/libshiboken/shibokenbuffer.cpp index 1d22306ba..853a87e84 100644 --- a/sources/shiboken2/libshiboken/shibokenbuffer.cpp +++ b/sources/shiboken2/libshiboken/shibokenbuffer.cpp @@ -56,6 +56,29 @@ void *Shiboken::Buffer::getPointer(PyObject *pyObj, Py_ssize_t *size) return const_cast<void *>(buffer); } +void *Shiboken::Buffer::copyData(PyObject *pyObj, Py_ssize_t *sizeIn) +{ + void *result = nullptr; + Py_ssize_t size = 0; + + Py_buffer view; + if (PyObject_GetBuffer(pyObj, &view, PyBUF_ND) == 0) { + size = view.len; + if (size) { + result = std::malloc(size); + if (result != nullptr) + std::memcpy(result, view.buf, size); + else + size = 0; + } + PyBuffer_Release(&view); + } + + if (sizeIn != nullptr) + *sizeIn = size; + return result; +} + PyObject *Shiboken::Buffer::newObject(void *memory, Py_ssize_t size, Type type) { if (size == 0) diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.h b/sources/shiboken2/libshiboken/shibokenbuffer.h index 48461efca..4cbba1147 100644 --- a/sources/shiboken2/libshiboken/shibokenbuffer.h +++ b/sources/shiboken2/libshiboken/shibokenbuffer.h @@ -61,6 +61,14 @@ namespace Buffer */ LIBSHIBOKEN_API void *getPointer(PyObject *pyObj, Py_ssize_t *size = nullptr); + /** + * Returns a copy of the buffer data which should be free'd. + * + * If the \p pyObj is a non-contiguous buffer a Python error is set. + * nullptr is returned for empty buffers. + */ + LIBSHIBOKEN_API void *copyData(PyObject *pyObj, Py_ssize_t *size = nullptr); + } // namespace Buffer } // namespace Shiboken |