Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
libqt5-qtdeclarative
libqt5-fix-crash-with-early-QObject-property-ac...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libqt5-fix-crash-with-early-QObject-property-access.patch of Package libqt5-qtdeclarative
From b0835b31fd456c30ea3fcaae6edc58212556477d Mon Sep 17 00:00:00 2001 From: Simon Hausmann <simon.hausmann@digia.com> Date: Thu, 21 Aug 2014 13:10:33 +0200 Subject: [PATCH] Fix crash with early QObject property access In the reported bug, it can happen that we try to access the compile-time resolved QObject property of an object that is referenced by id. The binding that uses this is triggered when the property changes but _also_ when the id referenced object gets either created or deleted. The first time the binding is evaluated is very early on, when the id referenced object is not created yet, so the binding evaluation fails. However the dependency is set up, and so later then the id referenced object is created and the id property is set on the context, the notification triggers and the binding is re-evaluated. During that binding evaluation a QObject property access happens by index on an object that doesn't have its VME meta-object set up yet. Therefore the property access fails and a crash occurs or the Q_ASSERT(property) assertion fails. The fix is to set register the id named object in the context _after_ the VME meta-object is setup. Task-number: QTBUG-40018 Change-Id: Ic2d7b4a0c49635efe68e93f2f6c316eb65f0c309 Reviewed-by: Lars Knoll <lars.knoll@digia.com> --- src/qml/qml/qqmlobjectcreator.cpp | 18 ++++++++++++----- src/qml/qml/qqmlobjectcreator_p.h | 2 ++ .../qml/qqmllanguage/data/earlyIdObjectAccess.qml | 23 ++++++++++++++++++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 10 ++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 tests/auto/qml/qqmllanguage/data/earlyIdObjectAccess.qml --- qtdeclarative-opensource-src-5.3.1.orig/src/qml/qml/qqmlobjectcreator.cpp +++ qtdeclarative-opensource-src-5.3.1/src/qml/qml/qqmlobjectcreator.cpp @@ -1013,6 +1013,13 @@ void QQmlObjectCreator::recordError(cons errors << error; } +void QQmlObjectCreator::registerObjectWithContextById(int objectIndex, QObject *instance) const +{ + QHash<int, int>::ConstIterator idEntry = objectIndexToId.find(objectIndex); + if (idEntry != objectIndexToId.constEnd()) + context->setIdProperty(idEntry.value(), instance); +} + QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) { QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler); @@ -1112,10 +1119,6 @@ QObject *QQmlObjectCreator::createInstan parserStatus->d = &sharedState->allParserStatusCallbacks.top(); } - QHash<int, int>::ConstIterator idEntry = objectIndexToId.find(index); - if (idEntry != objectIndexToId.constEnd()) - context->setIdProperty(idEntry.value(), instance); - // Register the context object in the context early on in order for pending binding // initialization to find it available. if (isContextObject) @@ -1130,8 +1133,10 @@ QObject *QQmlObjectCreator::createInstan } } - if (isComponent) + if (isComponent) { + registerObjectWithContextById(index, instance); return instance; + } QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index); Q_ASSERT(!cache.isNull()); @@ -1288,6 +1293,9 @@ bool QQmlObjectCreator::populateInstance } else { vmeMetaObject = QQmlVMEMetaObject::get(_qobject); } + + registerObjectWithContextById(index, _qobject); + qSwap(_propertyCache, cache); qSwap(_vmeMetaObject, vmeMetaObject); --- qtdeclarative-opensource-src-5.3.1.orig/src/qml/qml/qqmlobjectcreator_p.h +++ qtdeclarative-opensource-src-5.3.1/src/qml/qml/qqmlobjectcreator_p.h @@ -110,6 +110,8 @@ private: QString stringAt(int idx) const { return qmlUnit->header.stringAt(idx); } void recordError(const QV4::CompiledData::Location &location, const QString &description); + void registerObjectWithContextById(int objectIndex, QObject *instance) const; + enum Phase { Startup, CreatingObjects, --- /dev/null +++ qtdeclarative-opensource-src-5.3.1/tests/auto/qml/qqmllanguage/data/earlyIdObjectAccess.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Item { + visible: false + property bool success: false + property bool loading: true + + Item { + visible: someOtherItem.someProperty + onVisibleChanged: { + if (!visible) { + success = loading + } + } + } + + Item { + id: someOtherItem + property bool someProperty: true + } + + Component.onCompleted: loading = false +} --- qtdeclarative-opensource-src-5.3.1.orig/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ qtdeclarative-opensource-src-5.3.1/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -240,6 +240,8 @@ private slots: void noChildEvents(); + void earlyIdObjectAccess(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -3791,6 +3793,14 @@ void tst_qqmllanguage::noChildEvents() QCOMPARE(object->childAddedEventCount(), 0); } +void tst_qqmllanguage::earlyIdObjectAccess() +{ + QQmlComponent component(&engine, testFileUrl("earlyIdObjectAccess.qml")); + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o.isNull()); + QVERIFY(o->property("success").toBool()); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor