From 865c8687d94b0952babc9c512737aed19ec0e7b2 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Fri, 14 Jun 2024 19:12:01 +0200 Subject: [PATCH] QmlDesigner: fix crash at RewriterView::amendQmlText() RewriterView does not own m_textModifier, so it needs to be checked. Especially if it is called by a timer like in the amendQmlText() case. With m_textToModelMerger, its a different story because its an owned unique_ptr. So no need to check it. Change-Id: If19b58cc94ec5e8ddd68a8c12acba0f880cbdc6b Reviewed-by: Thomas Hartmann (cherry picked from commit 6bcf4c9dc739e60a249942854b348bec678c0c1a) Reviewed-by: Tim Jenssen --- .../designercore/include/rewriterview.h | 2 +- .../designercore/model/rewriterview.cpp | 54 ++++++++++--------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 0134349682e..58c0d12222e 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -196,7 +196,7 @@ private: //variables void handleProjectUpdate(); bool inErrorState() const { return !m_rewritingErrorMessage.isEmpty(); } - TextModifier *m_textModifier = nullptr; + QPointer m_textModifier; int transactionLevel = 0; bool m_modificationGroupActive = false; bool m_checkSemanticErrors = true; diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index d8812a76d06..7513dd26aff 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -88,6 +88,7 @@ Internal::TextToModelMerger *RewriterView::textToModelMerger() const void RewriterView::modelAttached(Model *model) { + QTC_ASSERT(m_textModifier, return); m_modelAttachPending = false; AbstractView::modelAttached(model); @@ -431,7 +432,7 @@ void RewriterView::deactivateTextMofifierChangeSignals() void RewriterView::auxiliaryDataChanged(const ModelNode &, AuxiliaryDataKeyView key, const QVariant &) { - if (m_restoringAuxData) + if (m_restoringAuxData || !m_textModifier) return; if (key.type == AuxiliaryDataType::Document) @@ -488,9 +489,9 @@ void RewriterView::amendQmlText() if (!model()->rewriterView()) return; + QTC_ASSERT(m_textModifier, return); emitCustomNotification(StartRewriterAmend); - const QString newQmlText = m_textModifier->text(); ModelAmender differenceHandler(m_textToModelMerger.data()); @@ -754,6 +755,7 @@ void RewriterView::enterErrorState(const QString &errorMessage) void RewriterView::resetToLastCorrectQml() { + QTC_ASSERT(m_textModifier, return); m_textModifier->textDocument()->undo(); m_textModifier->textDocument()->clearUndoRedoStacks(QTextDocument::RedoStack); ModelAmender differenceHandler(m_textToModelMerger.data()); @@ -766,6 +768,7 @@ void RewriterView::resetToLastCorrectQml() QMap RewriterView::extractText(const QList &nodes) const { + QTC_ASSERT(m_textModifier, return {}); QmlDesigner::ASTObjectTextExtractor extract(m_textModifier->text()); QMap result; @@ -792,6 +795,7 @@ int RewriterView::nodeOffset(const ModelNode &node) const */ int RewriterView::nodeLength(const ModelNode &node) const { + QTC_ASSERT(m_textModifier, return -1); ObjectLengthCalculator objectLengthCalculator; unsigned length; if (objectLengthCalculator(m_textModifier->text(), nodeOffset(node), length)) @@ -802,12 +806,14 @@ int RewriterView::nodeLength(const ModelNode &node) const int RewriterView::firstDefinitionInsideOffset(const ModelNode &node) const { + QTC_ASSERT(m_textModifier, return -1); FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text()); return firstDefinitionFinder(nodeOffset(node)); } int RewriterView::firstDefinitionInsideLength(const ModelNode &node) const { + QTC_ASSERT(m_textModifier, return -1); FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text()); const int offset = firstDefinitionFinder(nodeOffset(node)); @@ -831,6 +837,7 @@ static bool isInNodeDefinition(int nodeTextOffset, int nodeTextLength, int curso ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, int cursorPosition) const { + QTC_ASSERT(m_textModifier, return {}); using myPair = std::pair; std::vector data; @@ -1080,36 +1087,35 @@ void RewriterView::qmlTextChanged() { if (inErrorState()) return; + QTC_ASSERT(m_textModifier, return); - if (m_textToModelMerger && m_textModifier) { - const QString newQmlText = m_textModifier->text(); + const QString newQmlText = m_textModifier->text(); #if 0 - qDebug() << Q_FUNC_INFO; - qDebug() << "old:" << lastCorrectQmlSource; - qDebug() << "new:" << newQmlText; + qDebug() << Q_FUNC_INFO; + qDebug() << "old:" << lastCorrectQmlSource; + qDebug() << "new:" << newQmlText; #endif - switch (m_differenceHandling) { - case Validate: { - ModelValidator differenceHandler(m_textToModelMerger.data()); - if (m_textToModelMerger->load(newQmlText, differenceHandler)) - m_lastCorrectQmlSource = newQmlText; - break; - } + switch (m_differenceHandling) { + case Validate: { + ModelValidator differenceHandler(m_textToModelMerger.data()); + if (m_textToModelMerger->load(newQmlText, differenceHandler)) + m_lastCorrectQmlSource = newQmlText; + break; + } - case Amend: { - if (m_instantQmlTextUpdate || externalDependencies().instantQmlTextUpdate()) { - amendQmlText(); - } else { - if (externalDependencies().viewManagerUsesRewriterView(this)) { - externalDependencies().viewManagerDiableWidgets(); - m_amendTimer.start(); - } + case Amend: { + if (m_instantQmlTextUpdate || externalDependencies().instantQmlTextUpdate()) { + amendQmlText(); + } else { + if (externalDependencies().viewManagerUsesRewriterView(this)) { + externalDependencies().viewManagerDiableWidgets(); + m_amendTimer.start(); } - break; - } } + break; + } } }