From 659b575d19f318bb4d0248236ea16a9cd0a573ed Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 1 Jul 2019 11:04:39 +0200 Subject: qmlplugindump: dump enums also for composite types Change-Id: I2745d3df4fca77483313c70e5433339c444c7fd4 Fixes: QTBUG-76627 Reviewed-by: Simon Hausmann Reviewed-by: Fabian Kosmale --- .../data/dumper/CompositeWithEnum/Animal.qml | 15 +++++++++++++++ .../qmlplugindump/data/dumper/CompositeWithEnum/qmldir | 3 +++ tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp | 16 ++++++++++++++++ tools/qmlplugindump/main.cpp | 6 +++++- 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml create mode 100644 tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir diff --git a/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml new file mode 100644 index 0000000000..5bd7788a8c --- /dev/null +++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml @@ -0,0 +1,15 @@ +pragma Singleton +import QtQml 2.0 + +QtObject { + property string name + property string category + property string sound + property int size: Animal.SizeSmall + + enum SizeType { + SizeSmall, + SizeMedium, + SizeLarge + } +} diff --git a/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir new file mode 100644 index 0000000000..f08b348efa --- /dev/null +++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir @@ -0,0 +1,3 @@ +module dumper.CompositeWithEnum +singleton Animal 1.0 Animal.qml +depends QtQml 2.0 diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp index 17766a89b5..72356a4d84 100644 --- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp +++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp @@ -46,6 +46,7 @@ private slots: void builtins(); void singleton(); void compositeWithinSingleton(); + void compositeWithEnum(); void plugin_data(); void plugin(); @@ -135,6 +136,21 @@ void tst_qmlplugindump::compositeWithinSingleton() QVERIFY2(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")), qPrintable(result)); } +void tst_qmlplugindump::compositeWithEnum() +{ + QProcess dumper; + QStringList args; + args << QLatin1String("dumper.CompositeWithEnum") << QLatin1String("1.0") + << QLatin1String(QT_QMLTEST_DIR "/data"); + dumper.start(qmlplugindumpPath, args); + QVERIFY2(dumper.waitForStarted(), qPrintable(dumper.errorString())); + QVERIFY2(dumper.waitForFinished(), qPrintable(dumper.errorString())); + + const QString &result = dumper.readAllStandardOutput(); + QVERIFY2(result.contains(QLatin1String("exports: [\"Animal 1.0\"]")), qPrintable(result)); + QVERIFY2(result.contains(QLatin1String("Enum {")), qPrintable(result)); +} + void tst_qmlplugindump::plugin_data() { QTest::addColumn("import"); diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 67ffd5a555..b83aebb017 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -479,8 +479,12 @@ public: } } - for (const QMetaObject *meta : qAsConst(objectsToMerge)) + for (const QMetaObject *meta : qAsConst(objectsToMerge)) { + for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index) + dump(meta->enumerator(index)); + writeMetaContent(meta, &knownAttributes); + } qml->writeEndObject(); } -- cgit v1.2.3 From 2ca5ea6aaff9bfe0b92184454788698602e470bb Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 1 Jul 2019 16:01:36 +0200 Subject: Bump version Change-Id: Ib85af4ea4a4c139fdc0e909ab22fcc5951da0c46 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 58e82995bd..d42b39c2e7 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += warning_clean -MODULE_VERSION = 5.12.4 +MODULE_VERSION = 5.12.5 -- cgit v1.2.3 From cca5d1ec2f2c1f038c7c933b6c57d89888fc683b Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 1 Jul 2019 15:56:35 +0200 Subject: Fix bindings not being re-evaluated when changing context property Commit 7cb6dce1f3e140ea68d6b05281950f212fc99d38 introduced an optimization to remove bindings that after their initial evaluation had no dependencies or errors (such as when accessing properties not set yet). However when accessing a context property in a silent way -- using typeof -- then no error state is set and the binding is removed. Any later change of the context property results therefore in no binding re-evaluation. This patch skips the optimization on bindings that are associated with a context that has unresolved names. This fixes the concrete bug at the expense of disabling further optimizations in the context if other bindings access unresolved context properties. However since context properties are discouraged anyway, this may be an acceptable price to pay. Change-Id: I95e120a4f71e8ebe0ec1fc44e8703c75f920dd28 Fixes: QTBUG-76796 Reviewed-by: Ulf Hermann Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmlobjectcreator.cpp | 3 ++- .../data/preserveBindingWithUnresolvedNames.qml | 4 ++++ tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index d5b15a7a5a..1b2aa8ea3b 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1353,7 +1353,8 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru QQmlPropertyData::DontRemoveBinding); if (!b->isValueTypeProxy()) { QQmlBinding *binding = static_cast(b.data()); - if (!binding->hasError() && !binding->hasDependencies()) + if (!binding->hasError() && !binding->hasDependencies() + && binding->context() && !binding->context()->unresolvedNames) b->removeFromObject(); } diff --git a/tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml b/tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml new file mode 100644 index 0000000000..a57bafb07b --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + property string testTypeOf: typeof(contextProp) +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 18ff10b6f4..15bd9584df 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -356,6 +356,7 @@ private slots: void callPropertyOnUndefined(); void jumpStrictNotEqualUndefined(); void removeBindingsWithNoDependencies(); + void preserveBindingWithUnresolvedNames(); void temporaryDeadZone(); void importLexicalVariables_data(); void importLexicalVariables(); @@ -8815,6 +8816,18 @@ void tst_qqmlecmascript::removeBindingsWithNoDependencies() } +void tst_qqmlecmascript::preserveBindingWithUnresolvedNames() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("preserveBindingWithUnresolvedNames.qml")); + QScopedPointer object(component.create()); + QVERIFY(!object.isNull()); + QCOMPARE(object->property("testTypeOf").toString(), QString("undefined")); + QObject obj; + engine.rootContext()->setContextProperty("contextProp", &obj); + QCOMPARE(object->property("testTypeOf").toString(), QString("object")); +} + void tst_qqmlecmascript::temporaryDeadZone() { QJSEngine engine; -- cgit v1.2.3 From 29c61f83c98c269c1c862a668c0a91a1027ee2d2 Mon Sep 17 00:00:00 2001 From: Tom Scheler Date: Sun, 19 May 2019 18:16:34 +0200 Subject: Fix read access violation when using KeyNavigation attached property Setting the KeyNavigation.up property of an item to another item will implicitly set the reverse (KeyNavigation.down) property on that other item pointing back to the item. Once the item is destroyed, you will have an invalid pointer stored in the other item pointing to the destroyed item. Using QPointer<> instead of raw pointers fixes that issue, because they will become null on QObject's destruction. Added QQuickItem test that verifies the issue is solved. Fixes: QTBUG-75399 Change-Id: Ibb3e976c4eb9fcd81604bcc2eb757257d3653930 Reviewed-by: Shawn Rutledge Reviewed-by: Ulf Hermann --- src/quick/items/qquickitem_p.h | 13 ++++++------ .../data/keynavigationtest_implicitDestroy.qml | 13 ++++++++++++ tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 24 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 771228914b..f618bcf1c3 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -75,6 +75,7 @@ #include #include #include +#include #if QT_CONFIG(quick_shadereffect) #include @@ -682,12 +683,12 @@ public: : leftSet(false), rightSet(false), upSet(false), downSet(false), tabSet(false), backtabSet(false) {} - QQuickItem *left = nullptr; - QQuickItem *right = nullptr; - QQuickItem *up = nullptr; - QQuickItem *down = nullptr; - QQuickItem *tab = nullptr; - QQuickItem *backtab = nullptr; + QPointer left; + QPointer right; + QPointer up; + QPointer down; + QPointer tab; + QPointer backtab; bool leftSet : 1; bool rightSet : 1; bool upSet : 1; diff --git a/tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml b/tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml new file mode 100644 index 0000000000..54d20273da --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml @@ -0,0 +1,13 @@ +import QtQuick 2.12 + +Item { + id: root + + function createImplicitKeyNavigation() { + var item = Qt.createQmlObject("import QtQuick 2.0; Item { }", root); + item.KeyNavigation.up = root + item.destroy(); + + forceActiveFocus(); + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 7107f4d995..399535cfa6 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -86,6 +86,7 @@ private slots: void keyNavigation_RightToLeft(); void keyNavigation_skipNotVisible(); void keyNavigation_implicitSetting(); + void keyNavigation_implicitDestroy(); void keyNavigation_focusReason(); void keyNavigation_loop(); void layoutMirroring(); @@ -2164,6 +2165,29 @@ void tst_QQuickItem::keyNavigation_implicitSetting() delete window; } +// QTBUG-75399 +void tst_QQuickItem::keyNavigation_implicitDestroy() +{ + QQuickView view; + view.setSource(testFileUrl("keynavigationtest_implicitDestroy.qml")); + view.show(); + + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickItem *root = view.rootObject(); + QVERIFY(QMetaObject::invokeMethod(root, "createImplicitKeyNavigation")); + + // process events is necessary to trigger upcoming memory access violation + QTest::qWait(0); + + QVERIFY(root->hasActiveFocus()); + + QKeyEvent keyPress = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(&view, &keyPress); // <-- access violation happens here + // this should fail the test, even if the access violation does not occur + QVERIFY(!keyPress.isAccepted()); +} + void tst_QQuickItem::keyNavigation_focusReason() { QQuickView *window = new QQuickView(nullptr); -- cgit v1.2.3 From 6dffa5400fd056e3862a2f8905362679c1bb6be7 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 2 Jul 2019 16:37:05 +0200 Subject: QQmlDelegateModel: ref objects before allocating The allocation might run the garbage collector and that might delete the object before we ref it. Change-Id: I13cb74ab011a4eabc8df136023958791a2183df0 Reviewed-by: Simon Hausmann --- src/qml/types/qqmldelegatemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 63bc64d5e6..af328fbe2a 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -2656,10 +2656,10 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index) model->m_cacheMetaType->initializePrototype(); QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine; QV4::Scope scope(v4); + ++cacheItem->scriptRef; QV4::ScopedObject o(scope, v4->memoryManager->allocate(cacheItem)); QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value()); o->setPrototypeOf(p); - ++cacheItem->scriptRef; return QQmlV4Handle(o); } -- cgit v1.2.3