diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-10-04 17:18:15 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2014-10-09 17:41:39 +0200 |
commit | 9e71faae038de4c41c206f1321da1b37ab6ca8b1 (patch) | |
tree | bf8c38eecd7654b4178379778c218f7552a752d9 /tests/auto/qml/qqmlexpression | |
parent | 8c3d661163fc7517569f1a70ab70c2b23de25406 (diff) |
Fix QQmlExpression/QQmlScriptString/QQmlBinding crashes
In the QQmlScriptString we store the binding id and it is an index into the
runtimeFunctions array of the compilation unit. However we don't store the
compilation unit and instead in QQmlBinding and QQmlExpression try to retrieve
it from the cache via the context url (we have the context after all). That
turns out to be not a reliable way, as sometimes the URL might slightly differ
from the originally compiled cache (qrc:/// turning to qrc:/ maybe).
Consequently the type is (unnecessarily) compiled again and unfortunately not
_linked_, therefore the runtime functions array is empty. Another option is
that when the component was created from a QByteArray, then no entry exists in
the cache in the first place.
This patch addresses the problem by storing a reference to the compilation unit
in the QQmlContextData. That we can safely retrieve and it'll make sure the
compilation unit also stays alive.
In the process of that the manual reference counting was switched over to
QQmlRefCount and QQmlRefPointer for QV4::CompilationUnit.
Task-number: QTBUG-41193
Change-Id: I9111f9a3b65618e453954abcd789c039e65a94f7
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests/auto/qml/qqmlexpression')
-rw-r--r-- | tests/auto/qml/qqmlexpression/data/expressionFromDataComponent.qml | 6 | ||||
-rw-r--r-- | tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp | 26 |
2 files changed, 32 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlexpression/data/expressionFromDataComponent.qml b/tests/auto/qml/qqmlexpression/data/expressionFromDataComponent.qml new file mode 100644 index 0000000000..1aefdf0c42 --- /dev/null +++ b/tests/auto/qml/qqmlexpression/data/expressionFromDataComponent.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 +import Test 1.0 +TestObject { + scriptString: { return "success"; } +} + diff --git a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp index 12cb2dce83..f53ef82891 100644 --- a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp +++ b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp @@ -47,6 +47,7 @@ public: private slots: void scriptString(); void syntaxError(); + void expressionFromDataComponent(); }; class TestObject : public QObject @@ -108,6 +109,31 @@ void tst_qqmlexpression::syntaxError() QCOMPARE(v, QVariant()); } +void tst_qqmlexpression::expressionFromDataComponent() +{ + qmlRegisterType<TestObject>("Test", 1, 0, "TestObject"); + + QQmlEngine engine; + QQmlComponent c(&engine); + + QUrl url = testFileUrl("expressionFromDataComponent.qml"); + + { + QFile f(url.toLocalFile()); + QVERIFY(f.open(QIODevice::ReadOnly)); + c.setData(f.readAll(), url); + } + + QScopedPointer<TestObject> object; + object.reset(qobject_cast<TestObject*>(c.create())); + Q_ASSERT(!object.isNull()); + + QQmlExpression expression(object->scriptString()); + QVariant result = expression.evaluate(); + QVERIFY(result.type() == QVariant::String); + QCOMPARE(result.toString(), QStringLiteral("success")); +} + QTEST_MAIN(tst_qqmlexpression) #include "tst_qqmlexpression.moc" |