diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-03-13 14:16:27 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-03-14 13:15:23 +0000 |
commit | d93415ed8f0a180e6d6dfde7799386185910516c (patch) | |
tree | 7c95abecb45cae116e451051e1469fd6cc37950e | |
parent | 7a4cf5aea705a7b3ca0f014fa5eb8639e7a4f7b9 (diff) |
Fix crash when adding None to a QLayout
This caused a crash in PySide's addLayoutOwnership() code snippet,
whereas Qt errors out with a warning.
Guard all input parameters of the layout snippets with a check.
Rename the snippet "addownership-0" which is used for the itemAt()
functions "addownership-item-at" for clarity and add a check there.
Pick-to: 6.5
Fixes: PYSIDE-2638
Change-Id: Ia89532059e7a27cc38d790a0d17e24e19d68887f
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit c5a601ca958cbe0fd72c1201bddab872e353dfcf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml | 6 | ||||
-rw-r--r-- | sources/pyside6/PySide6/glue/qtwidgets.cpp | 41 |
2 files changed, 37 insertions, 10 deletions
diff --git a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml index 956dedbb0..f3f3ab6d9 100644 --- a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml @@ -1181,7 +1181,8 @@ <modify-argument index="return"> <define-ownership owner="default"/> </modify-argument> - <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="addownership-0"/> + <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" + snippet="addownership-item-at"/> </modify-function> <modify-function signature="removeWidget(QWidget*)"> @@ -1315,7 +1316,8 @@ <modify-argument index="return"> <define-ownership owner="default"/> </modify-argument> - <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="addownership-0"/> + <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" + snippet="addownership-item-at"/> </modify-function> <modify-function signature="addWidget(QWidget*,int,int,QFlags<Qt::AlignmentFlag>)"> <modify-argument index="4"> diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp index e6c835d3b..df21c5b51 100644 --- a/sources/pyside6/PySide6/glue/qtwidgets.cpp +++ b/sources/pyside6/PySide6/glue/qtwidgets.cpp @@ -217,11 +217,21 @@ if (_widget) { #ifndef _QLAYOUT_HELP_FUNCTIONS_ #define _QLAYOUT_HELP_FUNCTIONS_ // Guard for jumbo builds +static const char msgInvalidParameterAdd[] = + "Invalid parameter None passed to addLayoutOwnership()."; +static const char msgInvalidParameterRemoval[] = + "Invalid parameter None passed to removeLayoutOwnership()."; + void addLayoutOwnership(QLayout *layout, QLayoutItem *item); void removeLayoutOwnership(QLayout *layout, QWidget *widget); inline void addLayoutOwnership(QLayout *layout, QWidget *widget) { + if (layout == nullptr || widget == nullptr) { + PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd); + return; + } + //transfer ownership to parent widget QWidget *lw = layout->parentWidget(); QWidget *pw = widget->parentWidget(); @@ -248,6 +258,11 @@ inline void addLayoutOwnership(QLayout *layout, QWidget *widget) inline void addLayoutOwnership(QLayout *layout, QLayout *other) { + if (layout == nullptr || other == nullptr) { + PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd); + return; + } + //transfer all children widgets from other to layout parent widget QWidget *parent = layout->parentWidget(); if (!parent) { @@ -274,8 +289,11 @@ inline void addLayoutOwnership(QLayout *layout, QLayout *other) inline void addLayoutOwnership(QLayout *layout, QLayoutItem *item) { - if (!item) + + if (layout == nullptr || item == nullptr) { + PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd); return; + } if (QWidget *w = item->widget()) { addLayoutOwnership(layout, w); @@ -291,6 +309,11 @@ inline void addLayoutOwnership(QLayout *layout, QLayoutItem *item) static void removeWidgetFromLayout(QLayout *layout, QWidget *widget) { + if (layout == nullptr || widget == nullptr) { + PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval); + return; + } + if (QWidget *parent = widget->parentWidget()) { //give the ownership to parent Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent)); @@ -308,9 +331,8 @@ static void removeWidgetFromLayout(QLayout *layout, QWidget *widget) inline void removeLayoutOwnership(QLayout *layout, QLayoutItem *item) { - - if (item == nullptr) { - PyErr_Format(PyExc_RuntimeError, "Item for removal from layout is None, or invalid."); + if (layout == nullptr || item == nullptr) { + PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval); return; } @@ -329,8 +351,10 @@ inline void removeLayoutOwnership(QLayout *layout, QLayoutItem *item) inline void removeLayoutOwnership(QLayout *layout, QWidget *widget) { - if (!widget) + if (layout == nullptr || widget == nullptr) { + PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval); return; + } for (int i = 0, i_max = layout->count(); i < i_max; ++i) { QLayoutItem *item = layout->itemAt(i); @@ -347,9 +371,10 @@ inline void removeLayoutOwnership(QLayout *layout, QWidget *widget) %CPPSELF.setAlignment(%1); // @snippet qlayout-setalignment -// @snippet addownership-0 -addLayoutOwnership(%CPPSELF, %0); -// @snippet addownership-0 +// @snippet addownership-item-at +if (%0 != nullptr) + addLayoutOwnership(%CPPSELF, %0); +// @snippet addownership-item-at // @snippet addownership-1 addLayoutOwnership(%CPPSELF, %1); |