diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-12-10 15:30:50 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-12-11 06:13:37 +0100 |
commit | d62c216cbd09fb43302b146d5d8aca529f2b70a7 (patch) | |
tree | 4f92fa5e8550a07ca7a3f3c9f9e46a004416b677 /tests/auto/qml/qqmlproperty | |
parent | bea06407bc14e6c5d2102a64f4f8dcb8eca8f515 (diff) |
Don't crash when accessing QVariant data pointer
The write method is called with a QVariant, and even though the property
might be of a QObject type, the variant might not contain a QObject. So
accessing the variant data directly via QVariant::constData and
static_cast'ing the void* to QObject* is not safe.
Add an explicit check before accessing. An alternative would be to at
least Q_ASSERT that the result of the cast and a QVariant::value call is
the same, which would then not introduce any performance penalty in
release builds. However, users use release-builds of qml and Qt tooling
to write QML, and we writing wrong QML code should not crash then
either.
Include a test case that segfaults without the fix.
Pick-to: 6.2
Fixes: QTBUG-98367
Change-Id: Ib3ae82d03c9b2df6251ee88d5bd969dd4f796a41
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'tests/auto/qml/qqmlproperty')
-rw-r--r-- | tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml | 20 | ||||
-rw-r--r-- | tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 18 |
2 files changed, 38 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml b/tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml new file mode 100644 index 0000000000..d8a06aa5f9 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml @@ -0,0 +1,20 @@ +import QtQuick + +Item { + id: top; + visible:true; + width:300; + height:300 + Text { + id: text + width: 30; height: 30 + text: "1234.56" + font.bold: true + Binding { + target: text.font // which is not a QObject, so can't use it as a binding target + property: 'bold' + value: false; + when: width < 30 + } + } +} diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 58b37b8267..0d6f0d8d61 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -208,6 +208,8 @@ private slots: void initFlags(); void constructFromPlainMetaObject(); + + void bindToNonQObjectTarget(); private: QQmlEngine engine; }; @@ -2513,6 +2515,22 @@ void tst_qqmlproperty::constructFromPlainMetaObject() QVERIFY(data == nullptr); } +void tst_qqmlproperty::bindToNonQObjectTarget() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("bindToNonQObjectTarget.qml"); + QQmlComponent component(&engine, url); + + // Yes, we can still create the component. The result of the script expression will only be + // known once it's executed. + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + QTest::ignoreMessage(QtWarningMsg, + qPrintable(url.toString() + ":14:7: Unable to assign QFont to QObject*")); + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o.isNull()); +} + QTEST_MAIN(tst_qqmlproperty) #include "tst_qqmlproperty.moc" |