aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
diff options
context:
space:
mode:
authorSami Shalayel <sami.shalayel@qt.io>2022-06-10 11:55:15 +0200
committerSami Shalayel <sami.shalayel@qt.io>2022-06-27 13:15:59 +0200
commitcdcc41c8c1b49d6ed33e1d544a17232e8337c486 (patch)
tree1e99bb05160f80816eeb8d1b6bdb57fc3ff9dda2 /tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
parent4db70c1e5455a3a21dfd1e3b75ac1116778a0454 (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.cpp53
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"