[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [calligra] libs/textlayout: Text layout: Fix crash due to use of invalid FrameIterator
From:       Dag Andersen <danders () get2net ! dk>
Date:       2016-11-24 11:15:03
Message-ID: E1c9rzb-00027d-WD () code ! kde ! org
[Download RAW message or body]

Git commit 42faf48e6b3b63add45251d1253e9b581bacf79d by Dag Andersen.
Committed on 24/11/2016 at 11:14.
Pushed by danders into branch 'master'.

Text layout: Fix crash due to use of invalid FrameIterator

Summary:
To keep app responsive layouting is chopped up in parts and
an iterator is used to remember where to continue.
In some (unknown) situations the QTextFrame the iterator refers to is deleted.
This patch implements an isValid() method that is checked before the iterator is used.

The crash is easily triggered by adding a chart to words or sheets and
eg show grid or hide axis label.

Test Plan: Tested by creating complex document in words, checking that layout is sane and complete.

Reviewers: boemann

Reviewed By: boemann

Tags: #kexi, #calligra:_3.0

Differential Revision: https://phabricator.kde.org/D3468

M  +8    -0    libs/textlayout/FrameIterator.cpp
M  +6    -0    libs/textlayout/FrameIterator.h
M  +5    -1    libs/textlayout/KoTextLayoutArea.cpp

https://commits.kde.org/calligra/42faf48e6b3b63add45251d1253e9b581bacf79d

diff --git a/libs/textlayout/FrameIterator.cpp b/libs/textlayout/FrameIterator.cpp
index bde238c..a033e63 100644
--- a/libs/textlayout/FrameIterator.cpp
+++ b/libs/textlayout/FrameIterator.cpp
@@ -27,6 +27,7 @@
 FrameIterator::FrameIterator(QTextFrame *frame)
 {
     it = frame->begin();
+    m_frame = it.parentFrame();
     currentTableIterator = 0;
     currentSubFrameIterator = 0;
     lineTextStart = -1;
@@ -37,6 +38,7 @@ FrameIterator::FrameIterator(const QTextTableCell &cell)
 {
     Q_ASSERT(cell.isValid());
     it = cell.begin();
+    m_frame = it.parentFrame();
     currentTableIterator = 0;
     currentSubFrameIterator = 0;
     lineTextStart = -1;
@@ -46,6 +48,7 @@ FrameIterator::FrameIterator(const QTextTableCell &cell)
 FrameIterator::FrameIterator(FrameIterator *other)
 {
     it = other->it;
+    m_frame = it.parentFrame();
     masterPageName = other->masterPageName;
     lineTextStart = other->lineTextStart;
     fragmentIterator = other->fragmentIterator;
@@ -67,6 +70,11 @@ FrameIterator::~FrameIterator()
     delete currentSubFrameIterator;
 }
 
+bool FrameIterator::isValid() const
+{
+    return m_frame;
+}
+
 bool FrameIterator::operator ==(const FrameIterator &other) const
 {
     if (it != other.it)
diff --git a/libs/textlayout/FrameIterator.h b/libs/textlayout/FrameIterator.h
index 71e0c15..0975045 100644
--- a/libs/textlayout/FrameIterator.h
+++ b/libs/textlayout/FrameIterator.h
@@ -20,6 +20,7 @@
 #define FRAMEITERATOR_H
 
 #include <QTextFrame>
+#include <QPointer>
 
 class TableIterator;
 class QTextTableCell;
@@ -33,6 +34,8 @@ public:
     explicit FrameIterator(FrameIterator *other);
     ~FrameIterator();
 
+    bool isValid() const;
+
     bool operator ==(const FrameIterator &other) const;
 
     TableIterator *tableIterator(QTextTable *);
@@ -51,6 +54,9 @@ public:
     FrameIterator *currentSubFrameIterator;  //useful if it is pointing to a subFrame
 
     int endNoteIndex;
+
+private:
+    QPointer<QTextFrame> m_frame;
 };
 
 #endif
diff --git a/libs/textlayout/KoTextLayoutArea.cpp b/libs/textlayout/KoTextLayoutArea.cpp
index aebaf7e..91d9117 100644
--- a/libs/textlayout/KoTextLayoutArea.cpp
+++ b/libs/textlayout/KoTextLayoutArea.cpp
@@ -503,7 +503,11 @@ bool KoTextLayoutArea::layout(FrameIterator *cursor)
     d->blockRects.clear();
     delete d->endNotesArea;
     d->endNotesArea=0;
-    if (d->endOfArea) {
+    if (d->copyEndOfArea && !d->copyEndOfArea->isValid()) {
+        delete d->copyEndOfArea;
+        d->copyEndOfArea = 0;
+    }
+    if (d->endOfArea && d->endOfArea->isValid()) {
         delete d->copyEndOfArea;
         d->copyEndOfArea = new FrameIterator(d->endOfArea);
     }
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic