[kdelibs] backported fix, fixes crashing kdevelop, 4.5.1 only

thomasj thomasj at fedoraproject.org
Fri Sep 10 09:34:13 UTC 2010


commit 2a36ca610101c6066647f25ef68e95e08bd84a8b
Author: Thomas Janssen <thomasj at fedoraproject.org>
Date:   Fri Sep 10 11:34:16 2010 +0200

    backported fix, fixes crashing kdevelop, 4.5.1 only

 kdelibs.spec                                       |   12 +-
 ....5.1_fix_kdevelop-crash_katetextblock_cpp.patch |   19 ++
 ....1_fix_kdevelop-crash_katetexthistory_cpp.patch |  289 ++++++++++++++++++++
 ....5.1_fix_kdevelop-crash_katetexthistory_h.patch |   28 ++
 4 files changed, 347 insertions(+), 1 deletions(-)
---
diff --git a/kdelibs.spec b/kdelibs.spec
index 2a3fe81..23d345e 100644
--- a/kdelibs.spec
+++ b/kdelibs.spec
@@ -12,7 +12,7 @@
 
 Summary: KDE Libraries
 Version: 4.5.1
-Release: 3%{?dist}
+Release: 4%{?dist}
 
 Name: kdelibs
 Epoch: 6
@@ -82,6 +82,10 @@ Patch24: kdelibs-4.3.1-drkonq.patch
 # paths (like /usr/lib64) already! With this, we can drop
 # -DCMAKE_SKIP_RPATH:BOOL=ON (finally)
 Patch27: kdelibs-4.4.80-no_rpath.patch
+# patches backported, fixed in coming 4.5.2, fix crashing kdevelop
+Patch30: kdelibs_4.5.1_fix_kdevelop-crash_katetextblock_cpp.patch
+Patch31: kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_cpp.patch
+Patch32: kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_h.patch
 
 ## upstreamable
 # add gpg2 support to knewstuff, rough first try s/gpg/gpg2/
@@ -256,6 +260,9 @@ format for use with the Qt 4 Assistant or KDevelop 4.
 %patch50 -p1 -b .knewstuff_gpg2
 
 # upstream patches
+%patch30 -p0
+%patch31 -p0
+%patch32 -p0
 
 # security fix
 %patch200 -p1 -b .CVE-2009-2702
@@ -503,6 +510,9 @@ rm -rf %{buildroot}
 
 
 %changelog
+* Fri Sep 10 2010 Thomas Janssen <thomasj at fedoraproject.org> 4.5.1-4
+- backport patches to fix a crashing kdevelop (kde 4.5.1 only)
+
 * Fri Aug 27 2010 Kevin Kofler <Kevin at tigcc.ticalc.org> - 4.5.1-3
 - make building -apidocs-qch optional and disable it by default until fixed
 
diff --git a/kdelibs_4.5.1_fix_kdevelop-crash_katetextblock_cpp.patch b/kdelibs_4.5.1_fix_kdevelop-crash_katetextblock_cpp.patch
new file mode 100644
index 0000000..61ff9d7
--- /dev/null
+++ b/kdelibs_4.5.1_fix_kdevelop-crash_katetextblock_cpp.patch
@@ -0,0 +1,19 @@
+--- kate/buffer/katetextblock.cpp      2010/09/06 00:49:03     1171997
++++ kate/buffer/katetextblock.cpp      2010/09/06 00:49:36     1171998
+@@ -355,6 +355,7 @@
+ 
+   // get text
+   QString &textOfLine = m_lines[line]->textReadWrite ();
++  int oldLength = textOfLine.size ();
+ 
+   // check if valid column
+   Q_ASSERT (range.start().column() >= 0);
+@@ -371,7 +372,7 @@
+   /**
+    * notify the text history
+    */
+-  m_buffer->history().removeText (range);
++  m_buffer->history().removeText (range, oldLength);
+ 
+   /**
+    * cursor and range handling below
\ No newline at end of file
diff --git a/kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_cpp.patch b/kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_cpp.patch
new file mode 100644
index 0000000..7956d9f
--- /dev/null
+++ b/kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_cpp.patch
@@ -0,0 +1,289 @@
+--- kate/buffer/katetexthistory.cpp    2010/09/06 00:49:03     1171997
++++ kate/buffer/katetexthistory.cpp    2010/09/06 00:49:36     1171998
+@@ -94,7 +94,7 @@
+   addEntry (entry);
+ }
+ 
+-void TextHistory::removeText (const KTextEditor::Range &range)
++void TextHistory::removeText (const KTextEditor::Range &range, int oldLineLength)
+ {
+   // create and add new entry
+   Entry entry;
+@@ -102,6 +102,7 @@
+   entry.line = range.start().line ();
+   entry.column = range.start().column ();
+   entry.length = range.end().column() - range.start().column();
++  entry.oldLineLength = oldLineLength;
+   addEntry (entry);
+ }
+ 
+@@ -315,11 +316,131 @@
+   }
+ }
+ 
++void TextHistory::Entry::reverseTransformCursor (int &cursorLine, int &cursorColumn, bool moveOnInsert) const
++{   
++  /**
++   * handle all history types
++   */
++  switch (type) {
++    /**
++     * Wrap a line
++     */
++    case WrapLine:
++      /**
++       * ignore this line
++       */
++      if (cursorLine <= line)
++          return;
++        
++      /**
++       * next line is unwrapped
++       */
++      if (cursorLine == line + 1) {
++        /**
++         * adjust column
++         */
++        cursorColumn = cursorColumn + column;
++      }
++
++      /**
++       * always decrement cursor line
++       */
++      cursorLine -=  1;
++      return;
++
++    /**
++     * Unwrap a line
++     */
++    case UnwrapLine:
++      /**
++       * ignore lines before unwrapped one
++       */
++      if (cursorLine < line - 1)
++          return;
++        
++      /**
++       * we unwrap this line, try to adjust cursor column if needed
++       */
++      if (cursorLine == line - 1) {
++        /**
++         * skip cursors with to small columns
++         */
++        if (cursorColumn <= oldLineLength) {
++            if (cursorColumn < oldLineLength || !moveOnInsert)
++                return;
++        }
++          
++        cursorColumn -= oldLineLength;
++      }
++      
++      /**
++       * increase cursor line
++       */
++      cursorLine += 1;
++      return;
++
++    /**
++     * Insert text
++     */
++    case InsertText:
++      /**
++       * only interesting, if same line
++       */
++      if (cursorLine != line)
++        return;
++
++      // skip cursors with too small column
++      if (cursorColumn <= column)
++        return;
++
++      // patch column of cursor
++      if (cursorColumn - length < column)
++        cursorColumn = column;
++      else
++        cursorColumn -= length;
++
++      return;
++
++    /**
++     * Remove text
++     */
++    case RemoveText:
++      /**
++       * only interesting, if same line
++       */
++      if (cursorLine != line)
++        return;
++
++      // skip cursors with too small column
++      if (cursorColumn <= column)
++        if (cursorColumn < column || !moveOnInsert)
++          return;
++
++      // patch column of cursor
++      if (cursorColumn <= oldLineLength)
++        cursorColumn += length;
++
++      // special handling if cursor behind the real line, e.g. non-wrapping cursor in block selection mode
++      else if (cursorColumn < oldLineLength + length)
++        cursorColumn =  oldLineLength + length;
++      return;
++
++    /**
++     * nothing
++     */
++    default:
++      return;
++  }
++}
++
+ void TextHistory::transformCursor (int& line, int& column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision)
+ {
+   /**
+-   * -1 special meaning for toRevision
++   * -1 special meaning for from/toRevision
+    */
++  if (fromRevision == -1)
++    fromRevision = revision ();
++  
+   if (toRevision == -1)
+     toRevision = revision ();
+ 
+@@ -333,7 +454,7 @@
+    * some invariants must hold
+    */
+   Q_ASSERT (!m_historyEntries.empty ());
+-  Q_ASSERT (fromRevision < toRevision);
++  Q_ASSERT (fromRevision != toRevision);
+   Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
+   Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+   Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
+@@ -343,9 +464,20 @@
+    * transform cursor
+    */
+   bool moveOnInsert = insertBehavior == KTextEditor::MovingCursor::MoveOnInsert;
+-  for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
+-    const Entry &entry = m_historyEntries[rev];
+-    entry.transformCursor (line, column, moveOnInsert);
++  
++  /**
++   * forward or reverse transform?
++   */
++  if (toRevision > fromRevision) {
++    for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
++        const Entry &entry = m_historyEntries[rev];
++        entry.transformCursor (line, column, moveOnInsert);
++    }
++  } else {
++    for (int rev = fromRevision - m_firstHistoryEntryRevision; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) {
++        const Entry &entry = m_historyEntries[rev];
++        entry.reverseTransformCursor (line, column, moveOnInsert);
++    }
+   }
+ }
+ 
+@@ -361,8 +493,11 @@
+   }
+ 
+   /**
+-   * -1 special meaning for toRevision
++   * -1 special meaning for from/toRevision
+    */
++  if (fromRevision == -1)
++    fromRevision = revision ();
++
+   if (toRevision == -1)
+     toRevision = revision ();
+ 
+@@ -376,40 +511,68 @@
+    * some invariants must hold
+    */
+   Q_ASSERT (!m_historyEntries.empty ());
+-  Q_ASSERT (fromRevision < toRevision);
++  Q_ASSERT (fromRevision != toRevision);
+   Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
+   Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+   Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
+   Q_ASSERT (toRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+-
++  
+   /**
+    * transform cursors
+    */
+-
++      
+   // first: copy cursors, without range association
+   int startLine = range.start().line(), startColumn = range.start().column(), endLine = range.end().line(), endColumn = range.end().column();
+   
+   bool moveOnInsertStart = !(insertBehaviors & KTextEditor::MovingRange::ExpandLeft);
+   bool moveOnInsertEnd = (insertBehaviors & KTextEditor::MovingRange::ExpandRight);
+-  for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
+-    const Entry &entry = m_historyEntries[rev];
+-    
+-    entry.transformCursor (startLine, startColumn, moveOnInsertStart);
+-    
+-    entry.transformCursor (endLine, endColumn, moveOnInsertEnd);
+-
+-    // got empty?
+-    if(endLine < startLine || (endLine == startLine && endColumn <= startColumn))
+-    {
+-      if (invalidateIfEmpty) {
+-        range = KTextEditor::Range::invalid();
+-        return;
+-      }
+-      else{
+-        // else normalize them
+-        endLine = startLine;
+-        endColumn = startColumn;
+-      }
++  
++  /**
++   * forward or reverse transform?
++   */
++  if (toRevision > fromRevision) {
++    for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
++        const Entry &entry = m_historyEntries[rev];
++        
++        entry.transformCursor (startLine, startColumn, moveOnInsertStart);
++        
++        entry.transformCursor (endLine, endColumn, moveOnInsertEnd);
++
++        // got empty?
++        if(endLine < startLine || (endLine == startLine && endColumn <= startColumn))
++        {
++            if (invalidateIfEmpty) {
++                range = KTextEditor::Range::invalid();
++                return;
++            }
++            else{
++                // else normalize them
++                endLine = startLine;
++                endColumn = startColumn;
++            }
++        }
++    }
++  } else {
++    for (int rev = fromRevision - m_firstHistoryEntryRevision ; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) {
++        const Entry &entry = m_historyEntries[rev];
++        
++        entry.reverseTransformCursor (startLine, startColumn, moveOnInsertStart);
++        
++        entry.reverseTransformCursor (endLine, endColumn, moveOnInsertEnd);
++
++        // got empty?
++        if(endLine < startLine || (endLine == startLine && endColumn <= startColumn))
++        {
++            if (invalidateIfEmpty) {
++                range = KTextEditor::Range::invalid();
++                return;
++            }
++            else{
++                // else normalize them
++                endLine = startLine;
++                endColumn = startColumn;
++            }
++        }
+     }
+   }
+ 
\ No newline at end of file
diff --git a/kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_h.patch b/kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_h.patch
new file mode 100644
index 0000000..14506fa
--- /dev/null
+++ b/kdelibs_4.5.1_fix_kdevelop-crash_katetexthistory_h.patch
@@ -0,0 +1,28 @@
+--- kate/buffer/katetexthistory.h      2010/09/06 00:49:03     1171997
++++ kate/buffer/katetexthistory.h      2010/09/06 00:49:36     1171998
+@@ -99,6 +99,14 @@
+          * @param moveOnInsert behavior of this cursor on insert of text at it's position
+          */
+         void transformCursor (int &line, int &column, bool moveOnInsert) const;
++        
++        /**
++         * reverse transform cursor for this history entry
++         * @param line line number of the cursor to transform
++         * @param column column number of the cursor to transform
++         * @param moveOnInsert behavior of this cursor on insert of text at it's position
++         */
++        void reverseTransformCursor (int &line, int &column, bool moveOnInsert) const;
+ 
+         /**
+          * Types of entries, matching editing primitives of buffer and placeholder
+@@ -195,8 +203,9 @@
+     /**
+      * Notify about remove text at given range.
+      * @param range range of text to remove, must be on one line only.
++     * @param oldLineLength text length of the line before this remove
+      */
+-    void removeText (const KTextEditor::Range &range);
++    void removeText (const KTextEditor::Range &range, int oldLineLength);
+ 
+     /**
+      * Generic function to add a entry to the history. Is used by the above functions for the different editing primitives.
\ No newline at end of file


More information about the scm-commits mailing list