Commit 53b55e6f authored by Milian Wolff's avatar Milian Wolff

Fix UB when tracker gets destroyed

Don't cast partially destroyed object, fixes UBSAN report:

```
/home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/kdevplatform/language/highlighting/codehighlighting.cpp:612:21: runtime error: downcast of address 0x608000240320 which does not point to an object of type 'DocumentChangeTracker'
0x608000240320: note: object is of type 'QObject'
 14 01 80 2f  e0 84 05 4b 5d 7f 00 00  a0 03 24 00 80 60 00 00  10 ee 11 00 20 60 00 00  01 be be be
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'QObject'
    #0 0x7f5d566f5920 in KDevelop::CodeHighlighting::trackerDestroyed(QObject*) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/kdevplatform/language/highlighting/codehighlighting.cpp:612
```
parent 26be56d2
......@@ -508,7 +508,7 @@ void CodeHighlighting::clearHighlightingForDocument(const IndexedString& documen
DocumentChangeTracker* tracker = ICore::self()->languageController()->backgroundParser()->trackerForUrl(document);
auto highlightingIt = m_highlights.find(tracker);
if (highlightingIt != m_highlights.end()) {
disconnect(tracker, &DocumentChangeTracker::destroyed, this, &CodeHighlighting::trackerDestroyed);
disconnect(tracker, &DocumentChangeTracker::destroyed, this, nullptr);
auto& highlighting = *highlightingIt;
qDeleteAll(highlighting->m_highlightedRanges);
delete highlighting;
......@@ -553,7 +553,15 @@ void CodeHighlighting::applyHighlighting(void* _highlighting)
this, SLOT(aboutToInvalidateMovingInterfaceContent(KTextEditor::Document*)));
connect(tracker->document(), SIGNAL(aboutToRemoveText(KTextEditor::Range)),
this, SLOT(aboutToRemoveText(KTextEditor::Range)));
connect(tracker, &DocumentChangeTracker::destroyed, this, &CodeHighlighting::trackerDestroyed);
connect(tracker, &DocumentChangeTracker::destroyed, this, [this, tracker]() {
// Called when a document is destroyed
VERIFY_FOREGROUND_LOCKED
QMutexLocker lock(&m_dataMutex);
Q_ASSERT(m_highlights.contains(tracker));
delete m_highlights[tracker]; // No need to care about the individual ranges, as the document is being
// destroyed
m_highlights.remove(tracker);
});
m_highlights.insert(tracker, highlighting);
}
......@@ -604,17 +612,6 @@ void CodeHighlighting::applyHighlighting(void* _highlighting)
delete *movingIt; // Delete unmatched moving ranges behind
}
void CodeHighlighting::trackerDestroyed(QObject* object)
{
// Called when a document is destroyed
VERIFY_FOREGROUND_LOCKED
QMutexLocker lock(&m_dataMutex);
auto* tracker = static_cast<DocumentChangeTracker*>(object);
Q_ASSERT(m_highlights.contains(tracker));
delete m_highlights[tracker]; // No need to care about the individual ranges, as the document is being destroyed
m_highlights.remove(tracker);
}
void CodeHighlighting::aboutToInvalidateMovingInterfaceContent(Document* doc)
{
clearHighlightingForDocument(IndexedString(doc->url()));
......
......@@ -212,8 +212,6 @@ private Q_SLOTS:
void clearHighlightingForDocument(const KDevelop::IndexedString& document);
void applyHighlighting(void* highlighting);
void trackerDestroyed(QObject* object);
/// when the colors change we must invalidate our local caches
void adaptToColorChanges();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment