aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hartmann <thomas.hartmann@qt.io>2021-07-20 13:38:34 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-07-22 12:04:04 +0000
commitb79eaaf8b6662073345d26286369cad8207f0089 (patch)
treeb1e7b5cb5827d55e23505bf7771acb12d33241a7
parent29fbe538f6f4fbd5612dc55d85ba73d154d61781 (diff)
Avoid infinite loop in designer support
Task-number: QTBUG-94928 Change-Id: I1ee14600fb0fd9f0ee499546e3ffcd66114aaeff Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> (cherry picked from commit d3cae36550fe8b82c641cef6a207e991a9064d85) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/quick/designer/qquickdesignersupportproperties.cpp24
-rw-r--r--src/quick/designer/qquickdesignersupportproperties_p.h3
-rw-r--r--tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml8
-rw-r--r--tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml13
-rw-r--r--tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp47
5 files changed, 88 insertions, 7 deletions
diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp
index 8febf9a80a..9239f388a8 100644
--- a/src/quick/designer/qquickdesignersupportproperties.cpp
+++ b/src/quick/designer/qquickdesignersupportproperties.cpp
@@ -128,10 +128,14 @@ void QQuickDesignerSupportProperties::getPropertyCache(QObject *object, QQmlEngi
static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object,
const QQuickDesignerSupport::PropertyName &baseName,
- QObjectList *inspectedObjects)
+ QObjectList *inspectedObjects,
+ int depth = 0)
{
QQuickDesignerSupport::PropertyNameList propertyNameList;
+ if (depth > 2)
+ return propertyNameList;
+
if (!inspectedObjects->contains(object))
inspectedObjects->append(object);
@@ -145,14 +149,16 @@ static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProper
if (childObject)
propertyNameList.append(propertyNameListForWritableProperties(childObject,
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
- + '.', inspectedObjects));
+ + '.', inspectedObjects,
+ depth + 1));
}
} else if (QQmlGadgetPtrWrapper *valueType
= QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.metaType())) {
valueType->setValue(metaProperty.read(object));
propertyNameList.append(propertyNameListForWritableProperties(valueType,
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
- + '.', inspectedObjects));
+ + '.', inspectedObjects,
+ depth + 1));
}
if (metaProperty.isReadable() && metaProperty.isWritable()) {
@@ -183,7 +189,8 @@ bool QQuickDesignerSupportProperties::isPropertyBlackListed(const QQuickDesigner
QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allPropertyNames(QObject *object,
const QQuickDesignerSupport::PropertyName &baseName,
- QObjectList *inspectedObjects)
+ QObjectList *inspectedObjects,
+ int depth)
{
QQuickDesignerSupport::PropertyNameList propertyNameList;
@@ -192,6 +199,9 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
if (inspectedObjects == nullptr)
inspectedObjects = &localObjectList;
+ if (depth > 2)
+ return propertyNameList;
+
if (!inspectedObjects->contains(object))
inspectedObjects->append(object);
@@ -215,7 +225,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
propertyNameList.append(allPropertyNames(childObject,
baseName
+ QQuickDesignerSupport::PropertyName(metaProperty.name())
- + '.', inspectedObjects));
+ + '.', inspectedObjects,
+ depth + 1));
}
} else if (QQmlGadgetPtrWrapper *valueType
= QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.metaType())) {
@@ -224,7 +235,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
propertyNameList.append(allPropertyNames(valueType,
baseName
+ QQuickDesignerSupport::PropertyName(metaProperty.name())
- + '.', inspectedObjects));
+ + '.', inspectedObjects,
+ depth + 1));
} else {
addToPropertyNameListIfNotBlackListed(&propertyNameList,
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
diff --git a/src/quick/designer/qquickdesignersupportproperties_p.h b/src/quick/designer/qquickdesignersupportproperties_p.h
index 90961824a6..5970eca9f1 100644
--- a/src/quick/designer/qquickdesignersupportproperties_p.h
+++ b/src/quick/designer/qquickdesignersupportproperties_p.h
@@ -93,7 +93,8 @@ public:
static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object);
static QQuickDesignerSupport::PropertyNameList allPropertyNames(QObject *object,
const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(),
- QObjectList *inspectedObjects = nullptr);
+ QObjectList *inspectedObjects = nullptr,
+ int depth = 0);
static bool hasFullImplementedListInterface(const QQmlListReference &list);
};
diff --git a/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml b/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml
new file mode 100644
index 0000000000..ec419f8935
--- /dev/null
+++ b/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Item {
+ id: myObject
+ readonly property int testProperty: 0
+ readonly property QtObject myproperty: myObject
+}
+
diff --git a/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml b/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml
new file mode 100644
index 0000000000..4815709d21
--- /dev/null
+++ b/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.11
+
+Rectangle {
+ objectName: "rootItem"
+ color: "white"
+ width: 800
+ height: 600
+
+ RecursiveProperty {
+ objectName: "recursiveProperty"
+
+ }
+}
diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
index 18d6b6b5a7..ab01ae3a50 100644
--- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
+++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
@@ -66,6 +66,7 @@ private slots:
void testSimpleBindings();
void testDotProperties();
void testItemReparenting();
+ void testPropertyNames();
};
@@ -786,6 +787,52 @@ void tst_qquickdesignersupport::testItemReparenting()
QCOMPARE(text->parentItem(), item);
}
+void tst_qquickdesignersupport::testPropertyNames()
+{
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Crashes in QEMU. (QTBUG-90869)");
+#ifdef Q_CC_MINGW
+ QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869");
+#endif
+
+ QScopedPointer<QQuickView> view(new QQuickView);
+ view->engine()->setOutputWarningsToStandardError(false);
+ view->setSource(testFileUrl("propertyNameTest.qml"));
+
+ QVERIFY(view->errors().isEmpty());
+ QQuickItem *rootItem = view->rootObject();
+ QVERIFY(rootItem);
+
+ QQuickDesignerSupport::PropertyNameList names = QQuickDesignerSupportProperties::allPropertyNames(rootItem);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(names.contains("width"));
+ QVERIFY(names.contains("height"));
+ QVERIFY(names.contains("clip"));
+ QVERIFY(names.contains("childrenRect"));
+ QVERIFY(names.contains("activeFocus"));
+ QVERIFY(names.contains("border.width"));
+ names = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(rootItem);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(names.contains("width"));
+ QVERIFY(names.contains("height"));
+ QVERIFY(names.contains("opacity"));
+ QVERIFY(!names.contains("childrenRect"));
+ QVERIFY(!names.contains("childrenRect"));
+ QVERIFY(!names.contains("activeFocus"));
+ QVERIFY(names.contains("border.width"));
+
+ QQuickItem *recursiveProperty = findItem<QQuickItem>(rootItem, QLatin1String("recursiveProperty"));
+ QVERIFY(recursiveProperty);
+ names = QQuickDesignerSupportProperties::allPropertyNames(recursiveProperty);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(names.contains("testProperty"));
+ QVERIFY(names.contains("myproperty.testProperty"));
+
+ names = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(recursiveProperty);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(!names.contains("testProperty"));
+}
+
QTEST_MAIN(tst_qquickdesignersupport)
#include "tst_qquickdesignersupport.moc"