| Summary: | crash with comment functions | ||
|---|---|---|---|
| Product: | [Applications] kate | Reporter: | HolyCause <holy.cause> |
| Component: | general | Assignee: | KWrite Developers <kwrite-bugs-null> |
| Status: | RESOLVED FIXED | ||
| Severity: | crash | ||
| Priority: | NOR | ||
| Version First Reported In: | 2.5 | ||
| Target Milestone: | --- | ||
| Platform: | Ubuntu | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
HolyCause
2006-11-19 01:13:36 UTC
I just did another test, and it seems to happen every time I perform the [un]commenting pattern on that particular piece of code. I moved it into another existing file and Kate seg faulted again. paste the backtrace: [KCrash handler] #6 0xb75a6da2 in QString::insert () from /usr/lib/libqt-mt.so.3 #7 0xb6401332 in KateTextLine::insertText () from /usr/lib/kde3/libkatepart.so #8 0xb648a81a in KateDocument::editInsertText () from /usr/lib/kde3/libkatepart.so #9 0xb6496dc0 in KateDocument::insertText () from /usr/lib/kde3/libkatepart.so #10 0xb649733a in KateDocument::insertText () from /usr/lib/kde3/libkatepart.so #11 0xb646bdd5 in KateDocument::addStartStopCommentToSelection () from /usr/lib/kde3/libkatepart.so #12 0xb64b549e in KateDocument::comment () from /usr/lib/kde3/libkatepart.so #13 0xb64d6037 in KateView::comment () from /usr/lib/kde3/libkatepart.so #14 0xb64bb576 in KateView::qt_invoke () from /usr/lib/kde3/libkatepart.so #15 0xb7287957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #16 0xb72883fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #17 0xb6cd03b9 in KAction::activated () from /usr/lib/libkdeui.so.4 #18 0xb6d0dc02 in KAction::slotActivated () from /usr/lib/libkdeui.so.4 #19 0xb6dd654f in KAction::qt_invoke () from /usr/lib/libkdeui.so.4 #20 0xb7287957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #21 0xb72883fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #22 0xb782f249 in KAccelPrivate::menuItemActivated () from /usr/lib/libkdecore.so.4 #23 0xb787e3d7 in KAccelPrivate::emitActivatedSignal () from /usr/lib/libkdecore.so.4 #24 0xb791c46e in KAccelPrivate::eventFilter () from /usr/lib/libkdecore.so.4 #25 0xb7286f04 in QObject::activate_filters () from /usr/lib/libqt-mt.so.3 #26 0xb7286f82 in QObject::event () from /usr/lib/libqt-mt.so.3 #27 0xb72be65b in QWidget::event () from /usr/lib/libqt-mt.so.3 #28 0xb7394c5e in QMainWindow::event () from /usr/lib/libqt-mt.so.3 #29 0xb672497c in KateMainWindow::event () from /usr/lib/libkateinterfaces.so.0 #30 0xb721eb88 in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #31 0xb7220b58 in QApplication::notify () from /usr/lib/libqt-mt.so.3 #32 0xb7914db2 in KApplication::notify () from /usr/lib/libkdecore.so.4 #33 0xb788a777 in KAccelEventHandler::x11Event () from /usr/lib/libkdecore.so.4 #34 0xb79131e3 in KApplication::x11EventFilter () from /usr/lib/libkdecore.so.4 #35 0xb719d2d3 in qt_set_x11_event_filter () from /usr/lib/libqt-mt.so.3 #36 0xb71ada62 in QApplication::x11ProcessEvent () from /usr/lib/libqt-mt.so.3 #37 0xb71c5320 in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #38 0xb723925e in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #39 0xb723906e in QEventLoop::exec () from /usr/lib/libqt-mt.so.3 #40 0xb7220731 in QApplication::exec () from /usr/lib/libqt-mt.so.3 #41 0xb6784df3 in kdemain () from /usr/lib/libkdeinit_kate.so #42 0xb7f64524 in kdeinitmain () from /usr/lib/kde3/kate.so #43 0x0804e4df in ?? () can reproduce: 1. mark line 7-20 2. ctrl+c 3. ctrl+shift+d 4. ctrl+d 5. crash if step 2 is omitted, it does not crash. Valgrind trace: **3864** new/new[] failed and should throw an exception, but Valgrind cannot throw exceptions and so is aborting instead. Sorry. ==3864== at 0x4A20AE7: VALGRIND_PRINTF_BACKTRACE (valgrind.h:2366) ==3864== by 0x4A20D0C: operator new[](unsigned long) (vg_replace_malloc.c:199) ==3864== by 0x7C1BDAD: QString::setLength(unsigned) (in /usr/lib/libqt-mt.so.3.3.6) ==3864== by 0x7C1BF18: QString::grow(unsigned) (in /usr/lib/libqt-mt.so.3.3.6) ==3864== by 0x7C20876: QString::insert(unsigned, QChar const*, unsigned) (in /usr/lib/libqt-mt.so.3.3.6) ==3864== by 0xB2AAA50: KateTextLine::insertText(unsigned, unsigned, QChar const*, unsigned char*) (in /usr/lib/kde3/libkatepart.so) ==3864== by 0xB327DBF: KateDocument::editInsertText(unsigned, unsigned, QString const&) (in /usr/lib/kde3/libkatepart.so) ==3864== by 0xB333542: KateDocument::insertText(unsigned, unsigned, QString const&, bool) (in /usr/lib/kde3/libkatepart.so) ==3864== by 0xB333A5B: KateDocument::insertText(unsigned, unsigned, QString const&) (in /usr/lib/kde3/libkatepart.so) ==3864== by 0xB3047AB: KateDocument::addStartStopCommentToSelection(KateView*, int) (in /usr/lib/kde3/libkatepart.so) ==3864== by 0xB35278F: KateDocument::comment(KateView*, unsigned, unsigned, int) (in /usr/lib/kde3/libkatepart.so) ==3864== by 0xB3518AC: KateView::qt_invoke(int, QUObject*) (in /usr/lib/kde3/libkatepart.so) SVN commit 607385 by dhaumann: The view's selection selectStart and selectEnd are KateSuperCursors meaning that they have super-cow power. They are updated *automatically* when text is inserted or removed. A KateSuperCursor inserts itself into the document's super cursor list. In KateDocument::editRemove/InsertText there is a loop over all super cursors to keep them in sync. The 'un/comment' functions tried to adapt the super cursors themselves, although they were already updated. This resulted in negative columns, which somewhere wrapped around in a uint-conversion, which then set an insane selection, moo. This fixes the crash reported in bug #137555. Review and testing welcome! ;) CCMAIL:kwrite-devel@kde.org BUG:137555 M +2 -14 katedocument.cpp --- branches/KDE/3.5/kdelibs/kate/part/katedocument.cpp #607384:607385 @@ -3671,10 +3671,7 @@ removeText (sl, sc, sl, sc + startCommentLen); editEnd (); - - // Set the new selection - ec -= endCommentLen + ( (el == sl) ? startCommentLen : 0 ); - view->setSelection(sl, sc, el, ec + 1); + // set new selection not necessary, as the selection cursors are KateSuperCursors } return remove; @@ -3737,16 +3734,7 @@ } editEnd(); - - if (removed) - { - // Set the new selection - KateDocCursor end (view->selEnd()); - end.setCol(view->selEndCol() - ((el == view->selEndLine()) ? removeLength : 0) ); - - setSelection(view->selStartLine(), view->selStartCol(), end.line(), end.col()); - } - + // updating selection already done by the KateSuperCursors return removed; } SVN commit 607529 by dhaumann:
KateView:
* change selection KateSmartRange insert-behaviour to KTextEditor::SmartRange::ExpandRight
KateDocument: forward port SVN commit 607385:
* The view's selection range is a KateSmartRange. Due to its insert behaviour
being ExpandRight the selection range is automatically changed.
* code cleanup + review
CCBUG:137555
M +73 -111 katedocument.cpp
M +2 -2 katedocument.h
M +1 -1 kateview.cpp
--- trunk/KDE/kdelibs/kate/part/katedocument.cpp #607528:607529
@@ -3361,21 +3361,17 @@
Remove a given string at the beginning
of the current line.
*/
-bool KateDocument::removeStringFromBegining(int line, QString &str)
+bool KateDocument::removeStringFromBeginning(int line, const QString &str)
{
KateTextLine::Ptr textline = m_buffer->plainLine(line);
KTextEditor::Cursor cursor (line, 0);
- bool there = false;
+ bool there = textline->startsWith(str);
- if (textline->startsWith(str))
- there = true;
- else
+ if (!there)
{
cursor.setColumn(textline->firstChar());
-
- if ((cursor.column() >= 0) && ((int)textline->length() >= (cursor.column() + str.length())) && (textline->string(cursor.column(), str.length()) == str))
- there = true;
+ there = textline->matchesAt(cursor.column(), str);
}
if (there)
@@ -3391,24 +3387,21 @@
Remove a given string at the end
of the current line.
*/
-bool KateDocument::removeStringFromEnd(int line, QString &str)
+bool KateDocument::removeStringFromEnd(int line, const QString &str)
{
KateTextLine::Ptr textline = m_buffer->plainLine(line);
KTextEditor::Cursor cursor (line, 0);
- bool there = false;
+ bool there = textline->endsWith(str);
- if(textline->endsWith(str))
+ if (there)
{
cursor.setColumn(textline->length() - str.length());
- there = true;
}
else
{
cursor.setColumn(textline->lastChar() - str.length() + 1);
-
- if ((cursor.column() >= 0) && ((int)textline->length() >= (cursor.column() + str.length())) && (textline->string(cursor.column(), str.length()) == str))
- there = true;
+ there = textline->matchesAt(cursor.column(), str);
}
if (there)
@@ -3421,24 +3414,24 @@
}
/*
- Add to the current line a comment line mark at
- the beginning.
+ Add to the current line a comment line mark at the beginning.
*/
void KateDocument::addStartLineCommentToSingleLine( int line, int attrib )
{
- if (highlight()->getCommentSingleLinePosition(attrib)==KateHighlighting::CSLPosColumn0)
+ QString commentLineMark = highlight()->getCommentSingleLineStart(attrib);
+ int pos = -1;
+
+ if (highlight()->getCommentSingleLinePosition(attrib) == KateHighlighting::CSLPosColumn0)
{
- QString commentLineMark = highlight()->getCommentSingleLineStart( attrib ) + ' ';
- insertText (KTextEditor::Cursor(line, 0), commentLineMark);
+ pos = 0;
+ commentLineMark += ' ';
+ } else {
+ const KateTextLine::Ptr l = m_buffer->line(line);
+ pos = l->firstChar();
}
- else
- {
- QString commentLineMark=highlight()->getCommentSingleLineStart(attrib);
- KateTextLine::Ptr l = m_buffer->line(line);
- int pos=l->firstChar();
- if (pos >=0)
- insertText(KTextEditor::Cursor(line, pos), commentLineMark);
- }
+
+ if (pos >= 0)
+ insertText (KTextEditor::Cursor(line, pos), commentLineMark);
}
/*
@@ -3447,14 +3440,14 @@
*/
bool KateDocument::removeStartLineCommentFromSingleLine( int line, int attrib )
{
- QString shortCommentMark = highlight()->getCommentSingleLineStart( attrib );
- QString longCommentMark = shortCommentMark + ' ';
+ const QString shortCommentMark = highlight()->getCommentSingleLineStart( attrib );
+ const QString longCommentMark = shortCommentMark + ' ';
editStart();
// Try to remove the long comment mark first
- bool removed = (removeStringFromBegining(line, longCommentMark)
- || removeStringFromBegining(line, shortCommentMark));
+ bool removed = (removeStringFromBeginning(line, longCommentMark)
+ || removeStringFromBeginning(line, shortCommentMark));
editEnd();
@@ -3463,12 +3456,12 @@
/*
Add to the current line a start comment mark at the
- beginning and a stop comment mark at the end.
+ beginning and a stop comment mark at the end.
*/
void KateDocument::addStartStopCommentToSingleLine( int line, int attrib )
{
- QString startCommentMark = highlight()->getCommentStart( attrib ) + ' ';
- QString stopCommentMark = ' ' + highlight()->getCommentEnd( attrib );
+ const QString startCommentMark = highlight()->getCommentStart( attrib ) + ' ';
+ const QString stopCommentMark = ' ' + highlight()->getCommentEnd( attrib );
editStart();
@@ -3476,7 +3469,7 @@
insertText (KTextEditor::Cursor(line, 0), startCommentMark);
// Go to the end of the line
- int col = m_buffer->plainLine(line)->length();
+ const int col = m_buffer->plainLine(line)->length();
// Add the stop comment mark
insertText (KTextEditor::Cursor(line, col), stopCommentMark);
@@ -3501,15 +3494,15 @@
#warning "that's a bad idea, can lead to stray endings, FIXME"
#endif
// Try to remove the long start comment mark first
- bool removedStart = (removeStringFromBegining(line, longStartCommentMark)
- || removeStringFromBegining(line, shortStartCommentMark));
+ bool removedStart = (removeStringFromBeginning(line, longStartCommentMark)
+ || removeStringFromBeginning(line, shortStartCommentMark));
bool removedStop = false;
if (removedStart)
{
// Try to remove the long stop comment mark first
removedStop = (removeStringFromEnd(line, longStopCommentMark)
- || removeStringFromEnd(line, shortStopCommentMark));
+ || removeStringFromEnd(line, shortStopCommentMark));
}
editEnd();
@@ -3518,18 +3511,17 @@
}
/*
- Add to the current selection a start comment
- mark at the beginning and a stop comment mark
- at the end.
+ Add to the current selection a start comment mark at the beginning
+ and a stop comment mark at the end.
*/
void KateDocument::addStartStopCommentToSelection( KateView *view, int attrib )
{
- QString startComment = highlight()->getCommentStart( attrib );
- QString endComment = highlight()->getCommentEnd( attrib );
+ const QString startComment = highlight()->getCommentStart( attrib );
+ const QString endComment = highlight()->getCommentEnd( attrib );
KTextEditor::Range range = view->selectionRange();
- if ((range.end().column() == 0) && ((range.end().line() - 1) >= 0))
+ if ((range.end().column() == 0) && (range.end().line() > 0))
range.end().setPosition(range.end().line() - 1, lineLength(range.end().line() - 1));
editStart();
@@ -3538,24 +3530,21 @@
insertText (range.start(), startComment);
editEnd ();
-
- // Set the new selection
- range.end().setColumn(range.end().column() + endComment.length() + ( range.onSingleLine() ? startComment.length() : 0 ));
- view->setSelection(range);
+ // selection automatically updated (KateSmartRange)
}
/*
- Add to the current selection a comment line
- mark at the beginning of each line.
+ Add to the current selection a comment line mark at the beginning of each line.
*/
void KateDocument::addStartLineCommentToSelection( KateView *view, int attrib )
{
- QString commentLineMark = highlight()->getCommentSingleLineStart( attrib ) + ' ';
+ const QString commentLineMark = highlight()->getCommentSingleLineStart( attrib ) + ' ';
int sl = view->selectionRange().start().line();
int el = view->selectionRange().end().line();
- if ((view->selectionRange().end().column() == 0) && ((el-1) >= 0))
+ // if end of selection is in column 0 in last line, omit the last line
+ if ((view->selectionRange().end().column() == 0) && (el > 0))
{
el--;
}
@@ -3569,13 +3558,7 @@
}
editEnd ();
-
- // Set the new selection
-
- KateDocCursor end (view->selectionRange().end(), this);
- end.setColumn(view->selectionRange().end().column() + ((el == view->selectionRange().end().line()) ? commentLineMark.length() : 0) );
-
- view->setSelection(KTextEditor::Range(view->selectionRange().start().line(), 0, end.line(), end.column()));
+ // selection automatically updated (KateSmartRange)
}
bool KateDocument::nextNonSpaceCharPos(int &line, int &col)
@@ -3611,7 +3594,7 @@
if(line == 0) return false;
--line;
col = textLine->length();
-}
+ }
// No non-space char found
line = -1;
col = -1;
@@ -3624,8 +3607,8 @@
*/
bool KateDocument::removeStartStopCommentFromSelection( KateView *view, int attrib )
{
- QString startComment = highlight()->getCommentStart( attrib );
- QString endComment = highlight()->getCommentEnd( attrib );
+ const QString startComment = highlight()->getCommentStart( attrib );
+ const QString endComment = highlight()->getCommentEnd( attrib );
int sl = qMax<int> (0, view->selectionRange().start().line());
int el = qMin<int> (view->selectionRange().end().line(), lastLine());
@@ -3634,16 +3617,14 @@
// The selection ends on the char before selectEnd
if (ec != 0) {
- ec--;
- } else {
- if (el > 0) {
- el--;
- ec = m_buffer->plainLine(el)->length() - 1;
- }
+ --ec;
+ } else if (el > 0) {
+ --el;
+ ec = m_buffer->plainLine(el)->length() - 1;
}
- int startCommentLen = startComment.length();
- int endCommentLen = endComment.length();
+ const int startCommentLen = startComment.length();
+ const int endCommentLen = endComment.length();
// had this been perl or sed: s/^\s*$startComment(.+?)$endComment\s*/$2/
@@ -3660,10 +3641,7 @@
removeText (KTextEditor::Range(sl, sc, sl, sc + startCommentLen));
editEnd ();
-
- // Set the new selection
- ec -= endCommentLen + ( (el == sl) ? startCommentLen : 0 );
- view->setSelection(KTextEditor::Range(sl, sc, el, ec + 1));
+ // selection automatically updated (KateSmartRange)
}
return remove;
@@ -3671,21 +3649,20 @@
bool KateDocument::removeStartStopCommentFromRegion(const KTextEditor::Cursor &start,const KTextEditor::Cursor &end,int attrib)
{
- QString startComment = highlight()->getCommentStart( attrib );
- QString endComment = highlight()->getCommentEnd( attrib );
- int startCommentLen = startComment.length();
- int endCommentLen = endComment.length();
+ const QString startComment = highlight()->getCommentStart( attrib );
+ const QString endComment = highlight()->getCommentEnd( attrib );
+ const int startCommentLen = startComment.length();
+ const int endCommentLen = endComment.length();
- bool remove = m_buffer->plainLine(start.line())->matchesAt(start.column(), startComment)
- && ( (end.column() - endCommentLen ) >= 0 )
- && m_buffer->plainLine(end.line())->matchesAt(end.column() - endCommentLen , endComment);
- if (remove) {
- editStart();
- removeText(KTextEditor::Range(end.line(), end.column() - endCommentLen, end.line(), end.column()));
- removeText(KTextEditor::Range(start, startCommentLen));
- editEnd();
- }
- return remove;
+ const bool remove = m_buffer->plainLine(start.line())->matchesAt(start.column(), startComment)
+ && m_buffer->plainLine(end.line())->matchesAt(end.column() - endCommentLen , endComment);
+ if (remove) {
+ editStart();
+ removeText(KTextEditor::Range(end.line(), end.column() - endCommentLen, end.line(), end.column()));
+ removeText(KTextEditor::Range(start, startCommentLen));
+ editEnd();
+ }
+ return remove;
}
/*
@@ -3694,24 +3671,17 @@
*/
bool KateDocument::removeStartLineCommentFromSelection( KateView *view, int attrib )
{
- QString shortCommentMark = highlight()->getCommentSingleLineStart( attrib );
- QString longCommentMark = shortCommentMark + ' ';
+ const QString shortCommentMark = highlight()->getCommentSingleLineStart( attrib );
+ const QString longCommentMark = shortCommentMark + ' ';
int sl = view->selectionRange().start().line();
int el = view->selectionRange().end().line();
- if ((view->selectionRange().end().column() == 0) && ((el-1) >= 0))
+ if ((view->selectionRange().end().column() == 0) && (el > 0))
{
el--;
}
- // Find out how many char will be removed from the last line
- int removeLength = 0;
- if (m_buffer->plainLine(el)->startsWith(longCommentMark))
- removeLength = longCommentMark.length();
- else if (m_buffer->plainLine(el)->startsWith(shortCommentMark))
- removeLength = shortCommentMark.length();
-
bool removed = false;
editStart();
@@ -3720,22 +3690,14 @@
for (int z = el; z >= sl; z--)
{
// Try to remove the long comment mark first
- removed = (removeStringFromBegining(z, longCommentMark)
- || removeStringFromBegining(z, shortCommentMark)
- || removed);
+ removed = (removeStringFromBeginning(z, longCommentMark)
+ || removeStringFromBeginning(z, shortCommentMark)
+ || removed);
}
editEnd();
+ // selection automatically updated (KateSmartRange)
- if (removed)
- {
- // Set the new selection
- KateDocCursor end (view->selectionRange().end(), this);
- end.setColumn(view->selectionRange().end().column() - ((el == view->selectionRange().end().line()) ? removeLength : 0) );
-
- view->setSelection(KTextEditor::Range(view->selectionRange().start(), end));
- }
-
return removed;
}
--- trunk/KDE/kdelibs/kate/part/katedocument.h #607528:607529
@@ -674,8 +674,8 @@
void joinLines( uint first, uint last );
private:
- bool removeStringFromBegining(int line, QString &str);
- bool removeStringFromEnd(int line, QString &str);
+ bool removeStringFromBeginning(int line, const QString &str);
+ bool removeStringFromEnd(int line, const QString &str);
/**
Find the position (line and col) of the next char
--- trunk/KDE/kdelibs/kate/part/kateview.cpp #607528:607529
@@ -115,7 +115,7 @@
, m_hasWrap( false )
, m_startingUp (true)
, m_updatingDocumentConfig (false)
- , m_selection(m_doc->smartManager()->newSmartRange(KTextEditor::Range::invalid()))
+ , m_selection(m_doc->smartManager()->newSmartRange(KTextEditor::Range::invalid(), 0L, KTextEditor::SmartRange::ExpandRight))
, blockSelect (false)
, m_imComposeEvent( false )
{
|