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.

Pick-to: qds/4.5
Change-Id: If19b58cc94ec5e8ddd68a8c12acba0f880cbdc6b
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Tim Jenssen
2024-06-14 19:12:01 +02:00
parent 0d35eaced7
commit 6bcf4c9dc7
2 changed files with 32 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

@@ -99,6 +99,7 @@ Internal::TextToModelMerger *RewriterView::textToModelMerger() const
void RewriterView::modelAttached(Model *model)
{
QTC_ASSERT(m_textModifier, return);
m_modelAttachPending = false;
AbstractView::modelAttached(model);
@@ -457,7 +458,7 @@ void RewriterView::deactivateTextModifierChangeSignals()
void RewriterView::auxiliaryDataChanged(const ModelNode &, AuxiliaryDataKeyView key, const QVariant &)
{
if (m_restoringAuxData)
if (m_restoringAuxData || !m_textModifier)
return;
if (key.type == AuxiliaryDataType::Document)
@@ -522,9 +523,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.get());
@@ -765,6 +766,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.get());
@@ -777,6 +779,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;
@@ -803,6 +806,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))
@@ -813,12 +817,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));
@@ -842,6 +848,8 @@ 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;
@@ -1150,8 +1158,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
@@ -1180,7 +1188,6 @@ void RewriterView::qmlTextChanged()
break;
}
}
}
}
void RewriterView::delayedSetup()