Editor: Fix crash when removing mark from the block data destructor.

The TextBlockUserData is destructed from QTextBlockData::free which
deletes the layout right before. So triggering a direct update from
within this destructor could result in a crash when the already deleted
layout is used.

Task-number: QTCREATORBUG-16046
Change-Id: Ifd1d4334ba8ef47c41e0b9ae078ceaf1112b5908
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
David Schulz
2016-04-11 10:18:30 +02:00
parent 4e0b55f673
commit 1a5ebfbe05

View File

@@ -48,6 +48,7 @@
#include <QScrollBar> #include <QScrollBar>
#include <QStringList> #include <QStringList>
#include <QTextCodec> #include <QTextCodec>
#include <QTimer>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -852,10 +853,16 @@ void TextDocument::removeMarkFromMarksCache(TextMark *mark)
QTC_ASSERT(documentLayout, return); QTC_ASSERT(documentLayout, return);
d->m_marksCache.removeAll(mark); d->m_marksCache.removeAll(mark);
auto scheduleLayoutUpdate = [documentLayout](){
// make sure all destructors that may directly or indirectly call this function are
// completed before updating.
QTimer::singleShot(0, documentLayout, &QPlainTextDocumentLayout::requestUpdate);
};
if (d->m_marksCache.isEmpty()) { if (d->m_marksCache.isEmpty()) {
documentLayout->hasMarks = false; documentLayout->hasMarks = false;
documentLayout->maxMarkWidthFactor = 1.0; documentLayout->maxMarkWidthFactor = 1.0;
documentLayout->requestUpdate(); scheduleLayoutUpdate();
return; return;
} }
@@ -879,7 +886,7 @@ void TextDocument::removeMarkFromMarksCache(TextMark *mark)
if (maxWidthFactor != documentLayout->maxMarkWidthFactor) { if (maxWidthFactor != documentLayout->maxMarkWidthFactor) {
documentLayout->maxMarkWidthFactor = maxWidthFactor; documentLayout->maxMarkWidthFactor = maxWidthFactor;
documentLayout->requestUpdate(); scheduleLayoutUpdate();
} else { } else {
documentLayout->requestExtraAreaUpdate(); documentLayout->requestExtraAreaUpdate();
} }