forked from pool/libqt5-qtdeclarative
Accepting request 247019 from KDE:Qt5
1 OBS-URL: https://build.opensuse.org/request/show/247019 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtdeclarative?expand=0&rev=17
This commit is contained in:
parent
bffabcc34e
commit
e274cb3f76
142
libqt5-fix-crash-with-early-QObject-property-access.patch
Normal file
142
libqt5-fix-crash-with-early-QObject-property-access.patch
Normal file
@ -0,0 +1,142 @@
|
||||
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"
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user