[konversation] Crash in marker cleanup code (kde#210106)
Rex Dieter
rdieter at fedoraproject.org
Fri Oct 21 16:45:02 UTC 2011
commit c8eb8ebb48ac2e5bc3743a2949b003f5f4a6801e
Author: Rex Dieter <rdieter at fedoraproject.org>
Date: Fri Oct 21 11:45:01 2011 -0500
Crash in marker cleanup code (kde#210106)
... konversation-1.3.1-fix_scroll_background.patch | 0
konversation.spec | 16 +-
konverstation-1.3.1-kdebug210106.patch | 418 ++++++++++++++++++++
3 files changed, 431 insertions(+), 3 deletions(-)
---
diff --git a/konvi-1.3.1_fix-scroll_background.patch b/konversation-1.3.1-fix_scroll_background.patch
similarity index 100%
rename from konvi-1.3.1_fix-scroll_background.patch
rename to konversation-1.3.1-fix_scroll_background.patch
diff --git a/konversation.spec b/konversation.spec
index c90b6f1..94c21b0 100644
--- a/konversation.spec
+++ b/konversation.spec
@@ -1,7 +1,7 @@
Name: konversation
Version: 1.3.1
-Release: 4%{?dist}
+Release: 5%{?dist}
Summary: A user friendly IRC client
Group: Applications/Internet
@@ -10,7 +10,11 @@ URL: http://konversation.kde.org/
Source0: ftp://ftp.kde.org/pub/kde/%{?pre:un}stable/konversation/%{version}%{?pre:-%{pre}}/src/konversation-%{version}%{?pre:-%{pre}}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Patch10: konvi-1.3.1_fix-scroll_background.patch
+#Upstream patches
+Patch100: konversation-1.3.1-fix_scroll_background.patch
+# Crash in marker cleanup code [QList::*, IRCView::cullMarkedLine]
+# http://bugs.kde.org/210106
+Patch101: konverstation-1.3.1-kdebug210106.patch
BuildRequires: desktop-file-utils
BuildRequires: gettext
@@ -34,7 +38,10 @@ to chat windows; configurable background colors and much more
%prep
%setup -q -n %{name}-%{version}%{?pre:-%{pre}}
-%patch10 -p1
+
+%patch100 -p1 -b .fix_scroll_background
+%patch101 -p1 -b .kdebug210106
+
%build
mkdir -p %{_target_platform}
@@ -86,6 +93,9 @@ fi
%changelog
+* Fri Oct 21 2011 Rex Dieter <rdieter at fedoraproject.org> 1.3.1-5
+- Crash in marker cleanup code (kde#210106)
+
* Sat Mar 12 2011 Kevin Kofler <Kevin at tigcc.ticalc.org> - 1.3.1-4
- add Requires: qca-ossl
diff --git a/konverstation-1.3.1-kdebug210106.patch b/konverstation-1.3.1-kdebug210106.patch
new file mode 100644
index 0000000..ec31781
--- /dev/null
+++ b/konverstation-1.3.1-kdebug210106.patch
@@ -0,0 +1,418 @@
+From: eli mackenzie <argonel at gmail.com>
+Date: Fri, 30 Sep 2011 10:41:58 +0000
+Subject: reformulation of cbe876c for v1.3.1
+X-Git-Url: http://quickgit.kde.org/?p=konversation.git&a=commitdiff&h=4a9627ef625342b450b1101ac1575bab44b5641a
+---
+reformulation of cbe876c for v1.3.1
+
+CCBUG:210106
+---
+
+
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,15 @@
++Changes from 1.3.1 to 1.3.1 #4056.1
++This patch was created as a stop-gap measure to allow
++Konversation 1.3.1 to work with Qt 4.7.4 and newer. Nokia allowed a
++source-incompatible change to fix a bug in QtCreator, which
++causes Konversation to crash when keeping track of the marker and
++remember lines.
++
++As this is not a released version, do not report bugs against it.
++
++For more information about the Qt change, see QTBUG-20916.
++
++
+ Changes from 1.3 to 1.3.1:
+ Konversation 1.3.1 is a maintenance release that improves program behavior
+ and fixes defects, the most serious of which is a regression that unfortu-
+
+--- a/src/commit.h
++++ b/src/commit.h
+@@ -1,4 +1,4 @@
+ // This COMMIT number is added to version string to be used as "patch level"
+ #ifndef COMMIT
+-#define COMMIT 4056
++#define COMMIT 4056.1
+ #endif
+
+--- a/src/version.h
++++ b/src/version.h
+@@ -1,3 +1,3 @@
+ #ifndef KONVI_VERSION
+-#define KONVI_VERSION "1.3.1"
++#define KONVI_VERSION "1.3.1 #4056.1"
+ #endif
+
+--- a/src/viewer/ircview.cpp
++++ b/src/viewer/ircview.cpp
+@@ -11,7 +11,7 @@
+ Copyright (C) 2002 Dario Abatianni <eisfuchs at tigress.com>
+ Copyright (C) 2005-2007 Peter Simonsson <psn at linux.se>
+ Copyright (C) 2006-2008 Eike Hein <hein at kde.org>
+- Copyright (C) 2004-2009 Eli Mackenzie <argonel at gmail.com>
++ Copyright (C) 2004-2011 Eli Mackenzie <argonel at gmail.com>
+ */
+
+ #include "ircview.h"
+@@ -111,7 +111,10 @@ class SelectionPin
+ if (d->textCursor().hasSelection())
+ {
+ int end = d->document()->rootFrame()->lastPosition();
+- QTextBlock b = d->document()->lastBlock();
++
++ //WARNING if selection pins don't work in some build environments, we need to keep the result
++ d->document()->lastBlock();
++
+ pos = d->textCursor().position();
+ anc = d->textCursor().anchor();
+ if (pos != end && anc != end)
+@@ -132,7 +135,7 @@ class SelectionPin
+ };
+
+
+-IRCView::IRCView(QWidget* parent, Server* newServer) : KTextBrowser(parent), m_nextCullIsMarker(false), m_rememberLinePosition(-1), m_rememberLineDirtyBit(false), markerFormatObject(this)
++IRCView::IRCView(QWidget* parent, Server* newServer) : KTextBrowser(parent), m_rememberLine(0), m_lastMarkerLine(0), m_rememberLineDirtyBit(false), markerFormatObject(this)
+ {
+ m_copyUrlMenu = false;
+ m_resetScrollbar = true;
+@@ -325,34 +328,6 @@ bool IRCView::searchNext(bool reversed)
+ return find(m_pattern, m_searchFlags);
+ }
+
+-//// Marker lines
+-
+-#define _S(x) #x << (x)
+-void dump_doc(QTextDocument* document)
+-{
+- QTextBlock b(document->firstBlock());
+- while (b.isValid())
+- {
+- kDebug() << _S(b.position())
+- << _S(b.length())
+- << _S(b.userState())
+- ;
+- b=b.next();
+- };
+-}
+-
+-QDebug operator<<(QDebug dbg, QList<QTextBlock> &l)
+-{
+- dbg.space() << _S(l.count()) << endl;
+- for (int i=0; i< l.count(); ++i)
+- {
+- QTextBlock b=l[i];
+- dbg.space() << _S(i) << _S(b.blockNumber()) << _S(b.length()) << _S(b.userState()) << endl;
+- }
+-
+- return dbg.space();
+-}
+-
+ class IrcViewMimeData : public QMimeData
+ {
+ public:
+@@ -417,13 +392,52 @@ void IRCView::dropEvent(QDropEvent* e)
+ emit urlsDropped(KUrl::List::fromMimeData(e->mimeData(), KUrl::List::PreferLocalUrls));
+ }
+
++// Marker lines
++
++// This object gets stuffed into the userData field of a text block.
++// Qt does not give us a way to track blocks, so we have to
++// rely on the destructor of this object to notify us that a
++// block we care about was removed from the document. This does not
++// prevent the first block bug from deleting the wrong block's data,
++// however that should not result in a crash.
++struct Burr: public QTextBlockUserData
++{
++ Burr(IRCView* o, Burr* prev, QTextBlock b, int objFormat)
++ : m_block(b), m_format(objFormat), m_prev(prev), m_next(0),
++ m_owner(o)
++ {
++ if (m_prev)
++ m_prev->m_next = this;
++ }
++
++ ~Burr()
++ {
++ m_owner->blockDeleted(this);
++ unlink();
++ }
++
++ void unlink()
++ {
++ if (m_prev)
++ m_prev->m_next = m_next;
++ if (m_next)
++ m_next->m_prev = m_prev;
++ }
++
++ QTextBlock m_block;
++ int m_format;
++ Burr* m_prev, *m_next;
++ IRCView* m_owner;
++};
++
+ void IrcViewMarkerLine::drawObject(QPainter *painter, const QRectF &r, QTextDocument *doc, int posInDocument, const QTextFormat &format)
+ {
+ Q_UNUSED(format);
+
+ QTextBlock block=doc->findBlock(posInDocument);
+ QPen pen;
+- switch (block.userState())
++ Burr* b = dynamic_cast<Burr*>(block.userData());
++ switch (b->m_format)
+ {
+ case IRCView::BlockIsMarker:
+ pen.setColor(Preferences::self()->color(Preferences::ActionMessage));
+@@ -456,33 +470,36 @@ QSizeF IrcViewMarkerLine::intrinsicSize(
+ return QSizeF(width, 6); // FIXME this is a hardcoded value...
+ }
+
++QTextCharFormat IRCView::getFormat(ObjectFormats x)
++{
++ QTextCharFormat f;
++ f.setObjectType(x);
++ return f;
++}
++
++void IRCView::blockDeleted(Burr* b) //slot
++{
++ //tracking only the tail
++ if (b == m_lastMarkerLine)
++ m_lastMarkerLine = b->m_prev;
++
++ if (b == m_rememberLine)
++ m_rememberLine = 0;
++}
++
+ void IRCView::cullMarkedLine(int where, int rem, int add) //slot
+ {
+- if (where == 0 && add == 0 && rem !=0)
+- {
+- if (document()->blockCount() == 1 && document()->firstBlock().length() == 1)
+- {
++ int blockCount = document()->blockCount();
++ QTextBlock prime = document()->firstBlock();
++
++ if (prime.length() == 1 && document()->blockCount() == 1)
+ wipeLineParagraphs();
+- }
+- else
+- {
+- if (m_nextCullIsMarker)
+- {
+- //move the remember line up.. if the cull removed it, this will forget its position
+- if (m_rememberLinePosition >= 0)
+- --m_rememberLinePosition;
+- m_markers.takeFirst();
+- }
+- int s = document()->firstBlock().userState();
+- m_nextCullIsMarker = (s == BlockIsMarker || s == BlockIsRemember);
+- }
+- }
+ }
+
+ void IRCView::insertMarkerLine() //slot
+ {
+ //if the last line is already a marker of any kind, skip out
+- if (lastBlockIsLine())
++ if (lastBlockIsLine(BlockIsMarker))
+ return;
+
+ //the code used to preserve the dirty bit status, but that was never affected by appendLine...
+@@ -505,7 +522,12 @@ void IRCView::cancelRememberLine() //slo
+
+ bool IRCView::lastBlockIsLine(int select)
+ {
+- int state = document()->lastBlock().userState();
++ Burr *b = dynamic_cast<Burr*>(document()->lastBlock().userData());
++
++ int state = -1;
++
++ if (b)
++ state = b->m_format;
+
+ if (select == -1)
+ return (state == BlockIsRemember || state == BlockIsMarker);
+@@ -522,81 +544,51 @@ void IRCView::appendRememberLine()
+ if (lastBlockIsLine(BlockIsRemember))
+ return;
+
+- // if we already have a rememberline, remove the previous one
+- if (m_rememberLinePosition > -1)
++ if (m_rememberLine)
+ {
+- //get the block that is the remember line
+- QTextBlock rem = m_markers[m_rememberLinePosition];
+- m_markers.removeAt(m_rememberLinePosition); //probably will be in there only once
+- m_rememberLinePosition=-1;
++ QTextBlock rem = m_rememberLine->m_block;
+ voidLineBlock(rem);
++ if (m_rememberLine != 0)
++ {
++ kDebug() << "%%%%%%%%%%%%%%%%% m_rememberLine still set!";
++ // this probably means we had a block containing only 0x2029, so Scribe merged the userData/userState into the next
++ m_rememberLine = 0;
++ }
+ }
+
+- //tell the control we did stuff
+- //FIXME do we still do something like this?
+- //repaintChanged();
++ m_rememberLine = appendLine(IRCView::RememberLine);
+
+- //actually insert a line
+- appendLine(IRCView::RememberLine);
+-
+- //store the index of the remember line
+- m_rememberLinePosition = m_markers.count() - 1;
+ }
+
+ void IRCView::voidLineBlock(QTextBlock rem)
+ {
+- if (rem.blockNumber() == 0)
+- {
+- Q_ASSERT(m_nextCullIsMarker);
+- m_nextCullIsMarker = false;
+- }
+ QTextCursor c(rem);
+- //FIXME make sure this doesn't flicker
++
+ c.select(QTextCursor::BlockUnderCursor);
+ c.removeSelectedText();
+ }
+
+ void IRCView::clearLines()
+ {
+- //if we have a remember line, put it in the list
+- //its already in the list
+
+- kDebug() << _S(m_nextCullIsMarker) << _S(m_rememberLinePosition) << _S(textCursor().position()) << m_markers;
+- dump_doc(document());
+-
+- //are there any markers?
+- if (hasLines())
++ while (hasLines())
+ {
+- for (int i=0; i < m_markers.count(); ++i)
+- voidLineBlock(m_markers[i]);
+-
+- wipeLineParagraphs();
+-
+- //FIXME do we have this? //repaintChanged();
+- }
+-
++ //IRCView::blockDeleted takes care of the pointers
++ voidLineBlock(m_lastMarkerLine->m_block);
++ };
+ }
+
+ void IRCView::wipeLineParagraphs()
+ {
+- m_nextCullIsMarker = false;
+- m_rememberLinePosition = -1;
+- m_markers.clear();
++ m_rememberLine = m_lastMarkerLine = 0;
+ }
+
+ bool IRCView::hasLines()
+ {
+- return m_markers.count() > 0;
++ return m_lastMarkerLine != 0;
+ }
+
+-QTextCharFormat IRCView::getFormat(ObjectFormats x)
+-{
+- QTextCharFormat f;
+- f.setObjectType(x);
+- return f;
+-}
+-
+-void IRCView::appendLine(IRCView::ObjectFormats type)
++Burr* IRCView::appendLine(IRCView::ObjectFormats type)
+ {
+ ScrollBarPin barpin(verticalScrollBar());
+ SelectionPin selpin(this);
+@@ -604,13 +596,21 @@ void IRCView::appendLine(IRCView::Object
+ QTextCursor cursor(document());
+ cursor.movePosition(QTextCursor::End);
+
+- cursor.insertBlock();
++ if (cursor.block().length() > 1) // this will be a 0x2029
++ cursor.insertBlock();
+ cursor.insertText(QString(QChar::ObjectReplacementCharacter), getFormat(type));
+- cursor.block().setUserState(type == MarkerLine? BlockIsMarker : BlockIsRemember);
+
+- m_markers.append(cursor.block());
+-}
++ QTextBlock block = cursor.block();
++ Burr *b = new Burr(this, m_lastMarkerLine, block, type == MarkerLine? BlockIsMarker : BlockIsRemember);
++ block.setUserData(b);
++
++ m_lastMarkerLine = b;
+
++ //TODO figure out what this is for
++ cursor.setPosition(block.position());
++
++ return b;
++}
+
+ //// Other stuff
+
+
+--- a/src/viewer/ircview.h
++++ b/src/viewer/ircview.h
+@@ -24,7 +24,7 @@
+
+ class Server;
+ class ChatWindow;
+-
++class Burr;
+
+ class KToggleAction;
+ class KMenu;
+@@ -139,9 +139,10 @@ class IRCView : public KTextBrowser
+ void appendRememberLine();
+
+ /// Create a remember line and insert it.
+- void appendLine(ObjectFormats=MarkerLine);
++ /// @return - Pointer to the Burr that was inserted into the block
++ Burr* appendLine(ObjectFormats=MarkerLine);
+
+- /// Forget the position of the remember line and markers.
++ /// Convenience method - forget the position of the remember line and markers.
+ void wipeLineParagraphs();
+
+ /// Convenience method - is the last block any sort of line, or a specific line?
+@@ -154,16 +155,22 @@ class IRCView : public KTextBrowser
+ /// Shortcut to get an object format of the desired type
+ QTextCharFormat getFormat(ObjectFormats);
+
++ public slots:
++ // Doesn't have to be a slot, but what the hay.
++ /// Called *only* from ~Burr(), by QTextBlockData::free
++ void blockDeleted(Burr* b);
++
+ private slots:
+- /** Called to see if a marker is queued up for deletion. Only triggers if
+- "where" is the beginning and there was nothing added.
+- */
++ /** Called every time a change occurs to the document.
++ *
++ * Used to infer the clearing of the entire document,
++ * because Trolltech removed virtual from the method
++ * that would indicate authoritatively.
++ */
+ void cullMarkedLine(int, int, int);
+
+ private: //marker/remember line data
+- bool m_nextCullIsMarker; ///< the next time a cull occurs, it'll be a marker
+- QList<QTextBlock> m_markers; ///< what blocks are markers?
+- int m_rememberLinePosition; ///< position of remember line in m_markers
++ Burr *m_rememberLine, *m_lastMarkerLine;
+ bool m_rememberLineDirtyBit; ///< the next append needs a remember line
+ IrcViewMarkerLine markerFormatObject; ///< a QTextObjectInterface
+
+
More information about the scm-commits
mailing list