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 <thomas.hartmann@qt.io>
(cherry picked from commit 6bcf4c9dc7)
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tim Jenssen
2024-06-14 19:12:01 +02:00
parent 14800c1c0f
commit 865c8687d9
2 changed files with 31 additions and 25 deletions

View File

@@ -196,7 +196,7 @@ private: //variables
void handleProjectUpdate();
bool inErrorState() const { return !m_rewritingErrorMessage.isEmpty(); }
TextModifier *m_textModifier = nullptr;
QPointer<TextModifier> m_textModifier;
int transactionLevel = 0;
bool m_modificationGroupActive = false;
bool m_checkSemanticErrors = true;

View File

@@ -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<ModelNode, QString> RewriterView::extractText(const QList<ModelNode> &nodes) const
{
QTC_ASSERT(m_textModifier, return {});
QmlDesigner::ASTObjectTextExtractor extract(m_textModifier->text());
QMap<ModelNode, QString> 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<ModelNode,int>;
std::vector<myPair> data;
@@ -1080,8 +1087,8 @@ void RewriterView::qmlTextChanged()
{
if (inErrorState())
return;
QTC_ASSERT(m_textModifier, return);
if (m_textToModelMerger && m_textModifier) {
const QString newQmlText = m_textModifier->text();
#if 0
@@ -1110,7 +1117,6 @@ void RewriterView::qmlTextChanged()
break;
}
}
}
}
void RewriterView::delayedSetup()