From e22b624d9ab1f36021adb9cdbfa9b37054282bb8 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 14 Aug 2017 16:29:46 +0200 Subject: Fix crashes with closures created in QML components When closures created inside QML components are called after the surrounding component (and consequently QML context) has been destroyed, we are in a somewhat limited environment. Initially we would just crash as the calling QML context is not valid anymore. We can alleviate that by introducing reference counting on the context and letting the QML context wrapper keep a strong reference. This avoids the crashes and also ensures that at least imports continue to be accessible within these contexts (as the singleton test case demonstrates). Task-number: QTBUG-61781 Change-Id: I893f171842d01b0863d95a02ea738adc2620e236 Reviewed-by: Lars Knoll --- src/qml/qml/qqmltypeloader.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/qml/qml/qqmltypeloader.cpp') diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index ce795be757..342e6c0725 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2817,7 +2817,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent effectiveCtxt = 0; // Create the script context if required - QQmlContextData *ctxt = new QQmlContextData; + QQmlContextDataRef ctxt(new QQmlContextData); ctxt->isInternal = true; ctxt->isJSContext = true; if (shared) @@ -2837,7 +2837,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent } if (effectiveCtxt) { - ctxt->setParent(effectiveCtxt, true); + ctxt->setParent(effectiveCtxt); } else { ctxt->engine = parentCtxt->engine; // Fix for QTBUG-21620 } @@ -2859,12 +2859,10 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent if (!m_program) { if (shared) m_loaded = true; - ctxt->destroy(); return QV4::Encode::undefined(); } QV4::Scoped qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, 0)); - qmlContext->takeContextOwnership(); m_program->qmlContext.set(scope.engine, qmlContext); m_program->run(); -- cgit v1.2.3