97 lines
3.2 KiB
Diff
97 lines
3.2 KiB
Diff
From bbf3c4715a1569b26a3aa029046e26989efd6edc Mon Sep 17 00:00:00 2001
|
|
From: Mitch Curtis <mitch.curtis@qt.io>
|
|
Date: Wed, 10 Jan 2018 15:42:01 +0100
|
|
Subject: [PATCH 14/92] Fix crash when accessing a deleted object
|
|
|
|
In QObjectWrapper::query(), return QV4::Attr_Invalid if the object was
|
|
deleted.
|
|
|
|
Task-number: QTBUG-44153
|
|
Change-Id: I53e8be6196489c323b190dbfa20d2dda2a54315e
|
|
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
---
|
|
src/qml/jsruntime/qv4qobjectwrapper.cpp | 4 ++++
|
|
.../qml/qqmllanguage/data/accessDeletedObject.qml | 12 +++++++++++
|
|
tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 24 ++++++++++++++++++++++
|
|
3 files changed, 40 insertions(+)
|
|
create mode 100644 tests/auto/qml/qqmllanguage/data/accessDeletedObject.qml
|
|
|
|
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
|
|
index 326381f38..89c10e099 100644
|
|
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
|
|
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
|
|
@@ -651,6 +651,10 @@ void QObjectWrapper::put(Managed *m, String *name, const Value &value)
|
|
PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
|
|
{
|
|
const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
|
|
+ const QObject *thatObject = that->d()->object();
|
|
+ if (QQmlData::wasDeleted(thatObject))
|
|
+ return QV4::Object::query(m, name);
|
|
+
|
|
ExecutionEngine *engine = that->engine();
|
|
QQmlContextData *qmlContext = engine->callingQmlContext();
|
|
QQmlPropertyData local;
|
|
diff --git a/tests/auto/qml/qqmllanguage/data/accessDeletedObject.qml b/tests/auto/qml/qqmllanguage/data/accessDeletedObject.qml
|
|
new file mode 100644
|
|
index 000000000..e5151096e
|
|
--- /dev/null
|
|
+++ b/tests/auto/qml/qqmllanguage/data/accessDeletedObject.qml
|
|
@@ -0,0 +1,12 @@
|
|
+import QtQuick 2.0
|
|
+
|
|
+Item {
|
|
+ id: root
|
|
+
|
|
+ Component.onCompleted: {
|
|
+ var createdObject = objectCreator.create()
|
|
+ createdObject.del()
|
|
+ // Shouldn't crash.
|
|
+ var test = "index" in createdObject
|
|
+ }
|
|
+}
|
|
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
|
|
index b1a17afd2..1af57f924 100644
|
|
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
|
|
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
|
|
@@ -269,6 +269,8 @@ private slots:
|
|
|
|
void concurrentLoadQmlDir();
|
|
|
|
+ void accessDeletedObject();
|
|
+
|
|
private:
|
|
QQmlEngine engine;
|
|
QStringList defaultImportPathList;
|
|
@@ -4571,6 +4573,28 @@ void tst_qqmllanguage::concurrentLoadQmlDir()
|
|
engine.setImportPathList(defaultImportPathList);
|
|
}
|
|
|
|
+// Test that deleting an object and then accessing it doesn't crash.
|
|
+// QTBUG-44153
|
|
+class ObjectCreator : public QObject
|
|
+{
|
|
+ Q_OBJECT
|
|
+public slots:
|
|
+ QObject *create() { return (new ObjectCreator); }
|
|
+ void del() { delete this; }
|
|
+};
|
|
+
|
|
+void tst_qqmllanguage::accessDeletedObject()
|
|
+{
|
|
+ QQmlEngine engine;
|
|
+
|
|
+ engine.rootContext()->setContextProperty("objectCreator", new ObjectCreator);
|
|
+ QQmlComponent component(&engine, testFileUrl("accessDeletedObject.qml"));
|
|
+ VERIFY_ERRORS(0);
|
|
+
|
|
+ QScopedPointer<QObject> o(component.create());
|
|
+ QVERIFY(!o.isNull());
|
|
+}
|
|
+
|
|
QTEST_MAIN(tst_qqmllanguage)
|
|
|
|
#include "tst_qqmllanguage.moc"
|
|
--
|
|
2.14.3
|
|
|