aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-23 10:26:15 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-23 08:48:04 +0000
commiteaec83583fff3e3bf431f6179936b84f4acca553 (patch)
tree2dc06fd396a15436ce53b51803a55262def40256
parent1aecb24682075cbb99f21a367c399387b12257d0 (diff)
Fix crash when modifying objects used as prototypes
Changing the prototype of an object back and forth leads to a 'cyclic' reference in the internal class transition tables. If one of those objects then gets a new property, we would get an infinite stack recursion trying to update the internal class IDs of the classes using this prototype. Fixed by skipping protochanges and vtable changes in the update code. That's ok, as those classes will always be reached through other paths from the empty class. Task-number: QTBUG-68369 Change-Id: Ie54ca5171a92f8e8b146a91376e435478ff70185 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp18
2 files changed, 20 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 9da854e7d7..3bfcf358bf 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -533,6 +533,8 @@ void InternalClass::updateInternalClassIdRecursive()
id = engine->newInternalClassId();
for (auto &t : transitions) {
Q_ASSERT(t.lookup);
+ if (t.flags == InternalClassTransition::VTableChange || t.flags == InternalClassTransition::PrototypeChange)
+ continue;
t.lookup->updateInternalClassIdRecursive();
}
}
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index f862cdb048..c3a3926144 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -205,6 +205,8 @@ private slots:
void scriptScopes();
+ void protoChanges_QTBUG68369();
+
signals:
void testSignal();
};
@@ -4157,6 +4159,22 @@ void tst_QJSEngine::scriptScopes()
QCOMPARE(use.toInt(), 42);
}
+void tst_QJSEngine::protoChanges_QTBUG68369()
+{
+ QJSEngine engine;
+ QJSValue ok = engine.evaluate(
+ "var o = { x: true };"
+ "var p1 = {};"
+ "var p2 = {};"
+ "o.__proto__ = p1;"
+ "o.__proto__ = p2;"
+ "o.__proto__ = p1;"
+ "p1.y = true;"
+ "o.y"
+ );
+ QVERIFY(ok.toBool() == true);
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"