summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qlayout.cpp
diff options
context:
space:
mode:
authorThomas Fischer <fischer@unix-ag.uni-kl.de>2014-08-24 14:01:26 +0200
committerMarc Mutz <marc.mutz@kdab.com>2014-09-05 00:05:45 +0200
commit983dde1f2f3db76ab26e949d8c2f4f8b968b36be (patch)
treec092b9aa473e4ca41201ab1969f9139ff9db8585 /src/widgets/kernel/qlayout.cpp
parent8206a263ab9bca7fef191d299c05294a00ec1c8f (diff)
Avoid adding widget to its own layout
Widgets and layouts added or inserted to a layout are checked for: - Not being NULL - Not being the parent widget of a layout or the layout itself, respectively Without this commit, adding a widget to its own layout would result in a CPU-hogging infinite loop. Now, a warning is written to stderr and the add or insert function call is ignored. The checks are implemented as public functions of QLayoutPrivate and thus accessible in QLayout's descendants to be used in various "addWidget", "insertWidget", etc functions. Unlike 'classical' layouts like QGridLayout, QFormLayout does indeed accept widgets that are NULL. To not break this behavior, any call for the check functions first tests if the widget or layout, respectively, to test is NULL or not and calls the check only in the latter case. Automated tests for QBoxLayout, QGridLayout, and QFormLayout were added. For an unpatched Qt 5.3, each of those automated tests will freeze as explained in QTBUG-40609. For a fixed version, warning messages about invalid parameters to addWidget/addLayout/... calls will be read by QTest::ignoreMessage, resulting in a passed test. Change-Id: I1522d5727e643da3f7c025755975aca9f482676d Task-number: QTBUG-40609 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Diffstat (limited to 'src/widgets/kernel/qlayout.cpp')
-rw-r--r--src/widgets/kernel/qlayout.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index eb21a580b1..778514f47a 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -858,6 +858,47 @@ void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
}
/*!
+ Returns \c true if the \a widget can be added to the \a layout;
+ otherwise returns \c false.
+*/
+bool QLayoutPrivate::checkWidget(QWidget *widget) const
+{
+ Q_Q(const QLayout);
+ if (!widget) {
+ qWarning("QLayout: Cannot add a null widget to %s/%s", q->metaObject()->className(),
+ qPrintable(q->objectName()));
+ return false;
+ }
+ if (widget == q->parentWidget()) {
+ qWarning("QLayout: Cannot add parent widget %s/%s to its child layout %s/%s",
+ widget->metaObject()->className(), qPrintable(widget->objectName()),
+ q->metaObject()->className(), qPrintable(q->objectName()));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Returns \c true if the \a otherLayout can be added to the \a layout;
+ otherwise returns \c false.
+*/
+bool QLayoutPrivate::checkLayout(QLayout *otherLayout) const
+{
+ Q_Q(const QLayout);
+ if (!otherLayout) {
+ qWarning("QLayout: Cannot add a null layout to %s/%s", q->metaObject()->className(),
+ qPrintable(q->objectName()));
+ return false;
+ }
+ if (otherLayout == q) {
+ qWarning("QLayout: Cannot add layout %s/%s to itself", q->metaObject()->className(),
+ qPrintable(q->objectName()));
+ return false;
+ }
+ return true;
+}
+
+/*!
This function is called from \c addWidget() functions in
subclasses to add \a w as a managed widget of a layout.