diff options
author | Sami Shalayel <sami.shalayel@qt.io> | 2022-06-10 11:55:15 +0200 |
---|---|---|
committer | Sami Shalayel <sami.shalayel@qt.io> | 2022-06-27 13:15:59 +0200 |
commit | cdcc41c8c1b49d6ed33e1d544a17232e8337c486 (patch) | |
tree | 1e99bb05160f80816eeb8d1b6bdb57fc3ff9dda2 /tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | |
parent | 4db70c1e5455a3a21dfd1e3b75ac1116778a0454 (diff) |
Ensure QmlAttached attribute does not leak into derived types in C++
Use the QmlTypeHasMarker helper struct to disable Qml type attributes
for types that are not marked with the corresponding macros but merely
inherit them from a superclass.
This fixes the use of the QML_ATTACHED macro, other commits will follow
for the other attributes.
[ChangeLog][QtQml][Important Behavior Changes]
Attached properties are only accessible from classes directly decorated
with the QML_ATTACHED macro. Derived classes cannot inherit attached
properties. Classes attached using the old way (via QQmlTypeInfo) are
unchanged.
Task-number: QTBUG-104177
Change-Id: Ia5393101ba17049bc0917e32668abc69a5ffe9d7
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp')
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index d0d83ad9b1..96bef34a61 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -383,6 +383,7 @@ private slots: void componentMix(); void uncreatableAttached(); void resetGadgetProperty(); + void leakingAttributesQmlAttached(); private: QQmlEngine engine; @@ -7210,6 +7211,58 @@ void tst_qqmllanguage::resetGadgetProperty() QCOMPARE(m->m_gadget.value(), 25); } +void tst_qqmllanguage::leakingAttributesQmlAttached() +{ + // Check for leakage in the QML_ATTACHED macro + { + QQmlComponent c(&engine); + c.setData("import StaticTest\n" + "import QtQuick\n" + "Item {" + " OriginalQmlAttached.abc: true" + "}", + QUrl()); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(o); + QObject *attached = qmlAttachedPropertiesObject<OriginalQmlAttached>(o.data()); + QVERIFY(attached); + QCOMPARE(attached->property("abc"), QVariant(true)); + } + { + QQmlComponent c(&engine); + c.setData("import StaticTest\n" + "import QtQuick\n" + "Item {" + " LeakingQmlAttached.abc: true" + "}", + QUrl()); + QVERIFY(!c.isReady()); + } + + { + QQmlComponent c(&engine); + c.setData("import StaticTest\n" + "import QtQuick\n" + "Item {" + " DerivedQmlAttached.anotherAbc: \"I am not a bool.\"\n" + " OriginalQmlAttached.abc: true" + "}", + QUrl()); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(o); + + QObject *attached = qmlAttachedPropertiesObject<OriginalQmlAttached>(o.data()); + QVERIFY(attached); + QCOMPARE(attached->property("abc"), QVariant(true)); + + attached = qmlAttachedPropertiesObject<DerivedQmlAttached>(o.data()); + QVERIFY(attached); + QCOMPARE(attached->property("anotherAbc"), QVariant("I am not a bool.")); + } +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" |