diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-09-04 14:17:45 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-09-08 09:53:04 +0200 |
commit | 29b580340bfae617728a31a5f1f6bd4c89a7db40 (patch) | |
tree | 905ed6747b4408c34422ff8cdea30c8294190c8d | |
parent | a19479c8d78f5936c85d4fc312f8bddc30347b17 (diff) |
QQmlProperty: Accept badly capitalized signal handler names
... but warn about them. Apparently we did accept them prior to 6.4.
Fixes: QTBUG-116576
Change-Id: If890db85f5a8d71c0bcdfaf646ee9f01765a0b3c
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
(cherry picked from commit 2fc19f2c627802d26bd385a6c9cc1f6412852ee2)
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 23 | ||||
-rw-r--r-- | tests/auto/qml/qqmlconnections/data/badSignalHandlerName.qml | 15 | ||||
-rw-r--r-- | tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp | 21 |
3 files changed, 59 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 0e44df219f..ba6a0971f2 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -380,6 +380,9 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name, return false; }; + static constexpr QLatin1String On("on"); + static constexpr qsizetype StrlenOn = On.size(); + const QString terminalString = terminal.toString(); if (QmlIR::IRBuilder::isSignalPropertyName(terminalString)) { QString signalName = terminalString.mid(2); @@ -412,6 +415,26 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name, } else if (findSignalInMetaObject(signalName.toUtf8())) { return; } + } else if (terminalString.size() > StrlenOn && terminalString.startsWith(On)) { + // This is quite wrong. But we need it for backwards compatibility. + QString signalName = terminalString.sliced(2); + signalName.front() = signalName.front().toLower(); + + QString handlerName = On + signalName; + const auto end = handlerName.end(); + auto result = std::find_if( + std::next(handlerName.begin(), StrlenOn), end, + [](const QChar &c) { return c.isLetter(); }); + if (result != end) + *result = result->toUpper(); + + qWarning() + << terminalString + << "is not a properly capitalized signal handler name." + << handlerName + << "would be correct."; + if (findSignalInMetaObject(signalName.toUtf8())) + return; } if (ddata && ddata->propertyCache) { diff --git a/tests/auto/qml/qqmlconnections/data/badSignalHandlerName.qml b/tests/auto/qml/qqmlconnections/data/badSignalHandlerName.qml new file mode 100644 index 0000000000..921787aa36 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/badSignalHandlerName.qml @@ -0,0 +1,15 @@ +import QtQml + +QtObject { + id: root + signal _foo + + property int handled: 0 + + property Connections c: Connections { + target: root + function on_Foo() { root.handled += 1 } + function on_foo() { root.handled += 2 } + } +} + diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp index f23c474907..63dfe9a3db 100644 --- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -55,6 +55,7 @@ private slots: void bindToPropertyWithUnderscoreChangeHandler(); void invalidTarget(); + void badSignalHandlerName(); private: QQmlEngine engine; void prefixes(); @@ -485,6 +486,26 @@ void tst_qqmlconnections::invalidTarget() QTRY_VERIFY(root->objectName().isEmpty()); } +void tst_qqmlconnections::badSignalHandlerName() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("badSignalHandlerName.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + QTest::ignoreMessage( + QtWarningMsg, + "\"on_foo\" is not a properly capitalized signal handler name. " + "\"on_Foo\" would be correct."); + + QScopedPointer<QObject> root(component.create()); + QVERIFY(!root.isNull()); + + QCOMPARE(root->property("handled").toInt(), 0); + QMetaObject::invokeMethod(root.data(), "_foo"); + QCOMPARE(root->property("handled").toInt(), 3); +} + + QTEST_MAIN(tst_qqmlconnections) #include "tst_qqmlconnections.moc" |