From 452929cea1be97664f886509c3bd1b1a51dcf755 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 31 Jan 2024 15:17:19 +0100 Subject: QmlCompiler: Reject lookups on shadowable base types If the base type of a lookup is shadowable we cannot give any guarantees at all about what is going to happen. Only if the right hand side of the lookup is shadowable we can use our QVariant trick. Fixes: QTBUG-121734 Pick-to: 6.7 6.6 Change-Id: I969a842a6bc6d6a4446bfbfb50f1a7021b84049e Reviewed-by: Fabian Kosmale Reviewed-by: Qt CI Bot --- tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp') diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp index 88c4e2375f..b98da74716 100644 --- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp +++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp @@ -119,6 +119,7 @@ private slots: void importsFromImportPath(); void inPlaceDecrement(); void inaccessibleProperty(); + void indirectlyShadowable(); void infinities(); void infinitiesToInt(); void innerObjectNonShadowable(); @@ -2243,6 +2244,69 @@ void tst_QmlCppCodegen::inaccessibleProperty() QCOMPARE(o->property("c").toInt(), 5); } +void tst_QmlCppCodegen::indirectlyShadowable() +{ + QQmlEngine engine; + + const QString url = u"qrc:/qt/qml/TestTypes/indirectlyShadowable.qml"_s; + QQmlComponent c(&engine, QUrl(url)); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer o(c.create()); + QVERIFY(!o.isNull()); + + const auto verifyShadowable = [&](const QString &objectName) { + QObject *outer = o->property("outer").value(); + QVERIFY(outer); + QObject *inner = outer->property("inner").value(); + QVERIFY(inner); + QObject *shadowable = inner->property("shadowable").value(); + QVERIFY(shadowable); + QCOMPARE(shadowable->objectName(), objectName); + }; + + const auto verifyNotShadowable = [&](const QString &objectName) { + QObject *notShadowable = o->property("notShadowable").value(); + QCOMPARE(notShadowable->objectName(), objectName); + }; + + const auto verifyEvil = [&]() { + QObject *outer = o->property("outer").value(); + QVERIFY(outer); + QCOMPARE(outer->property("inner").toString(), u"evil"_s); + }; + + verifyShadowable(u"shadowable"_s); + verifyNotShadowable(u"notShadowable"_s); + + QMetaObject::invokeMethod(o.data(), "setInnerShadowable"); + + verifyShadowable(u"self"_s); + verifyNotShadowable(u"notShadowable"_s); + + QMetaObject::invokeMethod(o.data(), "getInnerShadowable"); + + verifyShadowable(u"self"_s); + verifyNotShadowable(u"self"_s); + + QMetaObject::invokeMethod(o.data(), "turnEvil"); + + verifyEvil(); + verifyNotShadowable(u"self"_s); + + // Does not produce an error message because JavaScript. + QMetaObject::invokeMethod(o.data(), "setInnerShadowable"); + + verifyEvil(); + verifyNotShadowable(u"self"_s); + + QTest::ignoreMessage( + QtWarningMsg, qPrintable(url + u":29: Error: Cannot assign [undefined] to QObject*"_s)); + QMetaObject::invokeMethod(o.data(), "getInnerShadowable"); + + verifyEvil(); + verifyNotShadowable(u"self"_s); +} + void tst_QmlCppCodegen::infinities() { QQmlEngine engine; -- cgit v1.2.3