From 87999238141588987b3cef6cd68ff62a7e3e8daa Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 23 Oct 2017 11:24:16 +0200 Subject: QQmlEngineDebugService: Check QML contexts for validity We should not operate on invalid QML contexts and once we have established a context to be valid we don't have to check the result of QQmlContextData::get anymore. Change-Id: I9106115ddf925c3572048f1fd334bdfd9a9cfca7 Reviewed-by: Lars Knoll --- .../qmldbg_debugger/qqmlenginedebugservice.cpp | 22 ++++++------ .../tst_qqmlenginedebugservice.cpp | 39 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 3d08c4c809..d2cf7dc57f 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -337,6 +337,9 @@ void QQmlEngineDebugServiceImpl::buildObjectList(QDataStream &message, QQmlContext *ctxt, const QList > &instances) { + if (!ctxt->isValid()) + return; + QQmlContextData *p = QQmlContextData::get(ctxt); QString ctxtName = ctxt->objectName(); @@ -399,11 +402,8 @@ QQmlEngineDebugServiceImpl::objectData(QObject *object) } QQmlContext *context = qmlContext(object); - if (context) { - QQmlContextData *cdata = QQmlContextData::get(context); - if (cdata) - rv.idString = cdata->findObjectId(object); - } + if (context && context->isValid()) + rv.idString = QQmlContextData::get(context)->findObjectId(object); rv.objectName = object->objectName(); rv.objectId = QQmlDebugService::idForObject(object); @@ -564,14 +564,14 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message) QObject *object = QQmlDebugService::objectForId(objectId); QQmlContext *context = qmlContext(object); - if (!context) { + if (!context || !context->isValid()) { QQmlEngine *engine = qobject_cast( QQmlDebugService::objectForId(engineId)); if (engine && m_engines.contains(engine)) context = engine->rootContext(); } QVariant result; - if (context) { + if (context && context->isValid()) { QQmlExpression exprObj(context, object, expr); bool undefined = false; QVariant value = exprObj.evaluate(&undefined); @@ -632,7 +632,7 @@ bool QQmlEngineDebugServiceImpl::setBinding(int objectId, QObject *object = objectForId(objectId); QQmlContext *context = qmlContext(object); - if (object && context) { + if (object && context && context->isValid()) { QQmlProperty property(object, propertyName, context); if (property.isValid()) { @@ -677,7 +677,7 @@ bool QQmlEngineDebugServiceImpl::resetBinding(int objectId, const QString &prope QObject *object = objectForId(objectId); QQmlContext *context = qmlContext(object); - if (object && context) { + if (object && context && context->isValid()) { QStringRef parentPropertyRef(&propertyName); const int idx = parentPropertyRef.indexOf(QLatin1Char('.')); if (idx != -1) @@ -732,11 +732,9 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth { QObject *object = objectForId(objectId); QQmlContext *context = qmlContext(object); - if (!object || !context || !context->engine()) + if (!object || !context || !context->isValid()) return false; QQmlContextData *contextData = QQmlContextData::get(context); - if (!contextData) - return false; QQmlPropertyData dummy; QQmlPropertyData *prop = diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index d9a4777115..57e95f7b89 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -99,6 +99,8 @@ private: const QmlDebugObjectReference &oref, bool recursive) const; + void getContexts(); + QQmlDebugConnection *m_conn; QQmlEngineDebugClient *m_dbg; QQmlEngine *m_engine; @@ -138,6 +140,7 @@ private slots: void regression_QTCREATORBUG_7451(); void queryObjectWithNonStreamableTypes(); void asynchronousCreate(); + void invalidContexts(); }; QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( @@ -248,6 +251,22 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( } } +void tst_QQmlEngineDebugService::getContexts() +{ + bool success = false; + + m_dbg->queryAvailableEngines(&success); + QVERIFY(success); + QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); + + QList engines = m_dbg->engines(); + QCOMPARE(engines.count(), 1); + m_dbg->queryRootContexts(engines.first().debugId, &success); + + QVERIFY(success); + QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); +} + void tst_QQmlEngineDebugService::initTestCase() { qmlRegisterType("Test", 1, 0, "NonScriptPropertyElement"); @@ -1289,6 +1308,26 @@ void tst_QQmlEngineDebugService::asynchronousCreate() { QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect")); } +void tst_QQmlEngineDebugService::invalidContexts() +{ + getContexts(); + const int base = m_dbg->rootContext().contexts.count(); + QQmlContext context(m_engine); + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), base + 1); + QQmlContextData *contextData = QQmlContextData::get(&context); + contextData->invalidate(); + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), base); + QQmlContextData *rootData = QQmlContextData::get(m_engine->rootContext()); + rootData->invalidate(); + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), 0); + contextData->setParent(rootData); // makes context valid again, but not root. + getContexts(); + QCOMPARE(m_dbg->rootContext().contexts.count(), 0); +} + int main(int argc, char *argv[]) { int _argc = argc + 1; -- cgit v1.2.3