aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-05-11 15:48:11 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-05-14 11:45:41 +0200
commit2641a665fbcf1d0326bde6e4f610e775881f8430 (patch)
tree50222fe86d2d652df80a15719eb11fbe5cc9cc2b /sources
parent967be4ead8781da67b71b177d124764de5fd0aa3 (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.xml4
-rw-r--r--sources/shiboken2/libshiboken/shibokenbuffer.cpp23
-rw-r--r--sources/shiboken2/libshiboken/shibokenbuffer.h8
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&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1));
- %0 = new %TYPE(ptr, %ARGS);
+ auto *ptr = reinterpret_cast&lt;uchar *&gt;(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