diff options
author | Thomas Hartmann <thomas.hartmann@qt.io> | 2021-07-20 13:38:34 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-07-22 12:04:04 +0000 |
commit | b79eaaf8b6662073345d26286369cad8207f0089 (patch) | |
tree | b1e7b5cb5827d55e23505bf7771acb12d33241a7 | |
parent | 29fbe538f6f4fbd5612dc55d85ba73d154d61781 (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>
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" |