From 7105eb6d0d46949e235d213cfe77dda95f16c6c5 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 11 Sep 2025 09:17:18 +0200 Subject: QmlCompiler: Guard against disappearing arrow functions You can override a QObject method with a JavaScript function and take away the JavaScript function later by swapping out objects. This should not crash. Pick-to: 6.10 6.9 Fixes: QTBUG-140074 Change-Id: I85b17f4f619235024d0f1a27b4ff4128c7a57083 Reviewed-by: Sami Shalayel --- tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | 51 ++++++++++++++++++++++ 1 file changed, 51 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 579f279e93..5780862b47 100644 --- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp +++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp @@ -103,6 +103,7 @@ private slots: void detachOnAssignment(); void detachedReferences(); void dialogButtonBox(); + void disappearingArrowFunction(); void enumConversion(); void enumFromBadSingleton(); void enumLookup(); @@ -1866,6 +1867,56 @@ void tst_QmlCppCodegen::dialogButtonBox() QPlatformDialogHelper::Ok | QPlatformDialogHelper::Cancel); } +void tst_QmlCppCodegen::disappearingArrowFunction() +{ + QQmlEngine engine; + const QUrl url(u"qrc:/qt/qml/TestTypes/disappearingArrowFunction.qml"_s); + QQmlComponent c(&engine, url); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer o(c.create()); + QVERIFY(!o.isNull()); + + QTest::ignoreMessage(QtDebugMsg, "5"); + o->setObjectName("no"); + + QMetaObject::invokeMethod(o.data(), "swapNone"); + QTest::ignoreMessage(QtDebugMsg, "Bart"); + o->setObjectName("nono"); + + QMetaObject::invokeMethod(o.data(), "swapNone"); + QTest::ignoreMessage(QtDebugMsg, "5"); + o->setObjectName("nonono"); + + const QRegularExpression warning( + QRegularExpression::escape(url.toString()) + + u"\\:15\\: TypeError\\: Property 'getName' of object " + "Person_QML_[0-9]+\\(0x[0-9a-f]+\\) is not a function"_s); + + QMetaObject::invokeMethod(o.data(), "swapEvil"); + QTest::ignoreMessage(QtWarningMsg, warning); + o->setObjectName("nononono"); + + QMetaObject::invokeMethod(o.data(), "swapEvil"); + QTest::ignoreMessage(QtDebugMsg, "5"); + o->setObjectName("nonononono"); + + QMetaObject::invokeMethod(o.data(), "swapNone"); + QTest::ignoreMessage(QtDebugMsg, "Bart"); + o->setObjectName("nononononono"); + + QMetaObject::invokeMethod(o.data(), "swapEvil"); + QTest::ignoreMessage(QtWarningMsg, warning); + o->setObjectName("nonononononono"); + + QMetaObject::invokeMethod(o.data(), "swapEvil"); + QTest::ignoreMessage(QtDebugMsg, "Bart"); + o->setObjectName("nononononononono"); + + QMetaObject::invokeMethod(o.data(), "swapNone"); + QTest::ignoreMessage(QtDebugMsg, "5"); + o->setObjectName("nonononononononono"); +} + void tst_QmlCppCodegen::enumConversion() { QQmlEngine engine; -- cgit v1.2.3