diff --git a/libqt5-fix-crash-with-early-QObject-property-access.patch b/libqt5-fix-crash-with-early-QObject-property-access.patch new file mode 100644 index 0000000..9ba1c80 --- /dev/null +++ b/libqt5-fix-crash-with-early-QObject-property-access.patch @@ -0,0 +1,142 @@ +From b0835b31fd456c30ea3fcaae6edc58212556477d Mon Sep 17 00:00:00 2001 +From: Simon Hausmann +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 +--- + 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::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::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 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 o(component.create()); ++ QVERIFY(!o.isNull()); ++ QVERIFY(o->property("success").toBool()); ++} ++ + QTEST_MAIN(tst_qqmllanguage) + + #include "tst_qqmllanguage.moc" diff --git a/libqt5-qtdeclarative.changes b/libqt5-qtdeclarative.changes index b2d00f8..fbccb2a 100644 --- a/libqt5-qtdeclarative.changes +++ b/libqt5-qtdeclarative.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Aug 29 09:49:55 UTC 2014 - mlin@suse.com + +- Added upstream patch libqt5-fix-crash-with-early-QObject-property-access.patch + * Fix crash with early QObject property access, QTBUG-40018 + ------------------------------------------------------------------- Tue Aug 5 18:06:49 UTC 2014 - hrvoje.senjan@gmail.com diff --git a/libqt5-qtdeclarative.spec b/libqt5-qtdeclarative.spec index ba22fa4..c63d61e 100644 --- a/libqt5-qtdeclarative.spec +++ b/libqt5-qtdeclarative.spec @@ -37,6 +37,8 @@ Url: http://qt.digia.com %endif Source: %{tar_version}.tar.xz Source1: baselibs.conf +# PATCH-FIX-UPSTREAM libqt5-fix-crash-with-early-QObject-property-access.patch -- QTBUG-40018 +Patch1000: libqt5-fix-crash-with-early-QObject-property-access.patch BuildRequires: fdupes BuildRequires: libQt5Core-private-headers-devel >= %{version} BuildRequires: libQt5Gui-private-headers-devel >= %{version} @@ -70,6 +72,7 @@ handling. %else %setup -q -n qtdeclarative-opensource-src-%{real_version} %endif +%patch1000 -p1 %package -n %libname Summary: Qt 5 Declarative Library