Bug 129580

Summary: crash pasting text via Ctrl-V
Product: [Applications] kate Reporter: Vadym Krevs <vkrevs>
Component: indentationAssignee: KWrite Developers <kwrite-bugs-null>
Status: RESOLVED FIXED    
Severity: crash CC: esigra, stefan.nikolaus
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Potential fix

Description Vadym Krevs 2006-06-21 17:19:19 UTC
Version:           3.3.3 (using KDE 3.5.3 Level "a" , unofficial build of SUSE )
Compiler:          Target: x86_64-suse-linux
OS:                Linux (x86_64) release 2.6.16.13-4-smp

Selected some text,moved cursor and hit Ctrl-V. Kdevep crashed with the following stack trace.

System configuration startup check disabled.

Using host libthread_db library "/lib64/libthread_db.so.1".
[Thread debugging using libthread_db enabled]
[New Thread 47042752454736 (LWP 22884)]
[New Thread 1082132800 (LWP 22905)]
[KCrash handler]
#5  0x00002aaaabd7c333 in KateTextLine::stringAtPos (
    this=<value optimized out>, pos=4294967295, match=<value optimized out>)
    at ./kate/part/katetextline.cpp:191
#6  0x00002aaaabdfa137 in KateCSmartIndent::calcContinue (this=0x6ec9c10, 
    start=@0x7fffb1cf9400, end=@0x7fffb1cf9550)
    at ./kate/part/kateautoindent.cpp:894
#7  0x00002aaaabdfb025 in KateCSmartIndent::calcIndent (this=0x6ec9c10, 
    begin=@0x7fffb1cf9550, needContinue=true)
    at ./kate/part/kateautoindent.cpp:778
#8  0x00002aaaabdfbb3c in KateCSmartIndent::processLine (this=0x6ec9c10, 
    line=@0x7fffb1cf9660) at ./kate/part/kateautoindent.cpp:502
#9  0x00002aaaabd90c87 in KateCSmartIndent::processSection (this=0x6ec9c10, 
    begin=<value optimized out>, end=@0x7fffb1cf96d0)
    at ./kate/part/kateautoindent.cpp:531
#10 0x00002aaaabe1e2ca in KateDocument::paste (this=0x71384d0, view=0x7137510)
    at ./kate/part/katedocument.cpp:3186
#11 0x00002aaaabe410f3 in KateView::paste (this=0x7137510)
    at ./kate/part/kateview.h:86
#12 0x00002aaaabe29077 in KateView::qt_invoke (this=0x7137510, _id=105, 
    _o=0x7fffb1cf98c0) at ./kate/part/kateview.moc:707
#13 0x00002ac8fa3aba8c in QObject::activate_signal (this=0x7146a90, 
    clist=<value optimized out>, o=0x7fffb1cf98c0) at kernel/qobject.cpp:2356
#14 0x00002ac8fa3ac7a3 in QObject::activate_signal (this=0x59b5150, 
    signal=<value optimized out>) at kernel/qobject.cpp:2325
#15 0x00002ac8f98c37e8 in KPasteTextAction::slotActivated (this=0x7146a90)
    at ./kdeui/kactionclasses.cpp:2371
#16 0x00002ac8f996830c in KPasteTextAction::qt_invoke (this=0x7146a90, _id=20, 
    _o=0x7fffb1cf99c0) at ./kdeui/kactionclasses.moc:1535
#17 0x00002ac8fa3aba8c in QObject::activate_signal (this=0x7e59df0, 
    clist=<value optimized out>, o=0x7fffb1cf99c0) at kernel/qobject.cpp:2356
#18 0x00002ac8fa3ac7a3 in QObject::activate_signal (this=0x59b5150, 
    signal=<value optimized out>) at kernel/qobject.cpp:2325
#19 0x00002ac8f9ccdb05 in KAccelPrivate::emitActivatedSignal (this=0x7e59df0, 
    pAction=0x565a240) at ./kdecore/kaccel.cpp:400
#20 0x00002ac8f9d40d8f in KAccelPrivate::eventFilter (this=0x7e59df0, 
    pEvent=0x7fffb1cf9e80) at ./kdecore/kaccel.cpp:370
#21 0x00002ac8fa3ab492 in QObject::activate_filters (this=0x6698e0, 
    e=0x7fffb1cf9e80) at kernel/qobject.cpp:903
#22 0x00002ac8fa3ab4e7 in QObject::event (this=0x6698e0, e=0x7fffb1cf9e80)
    at kernel/qobject.cpp:735
#23 0x00002ac8fa3de5c8 in QWidget::event (this=0x59b5150, e=0xffffffff)
    at kernel/qwidget.cpp:4678
#24 0x00002ac8fa48a065 in QMainWindow::event (this=0x6698e0, e=0x7fffb1cf9e80)
    at widgets/qmainwindow.cpp:1687
#25 0x00002ac8fb4b43b6 in KMdiMainFrm::event (this=0x6698e0, e=0x7fffb1cf9e80)
    at ./kmdi/kmdimainfrm.cpp:1162
#26 0x00002ac8fa354a95 in QApplication::internalNotify (
    this=<value optimized out>, receiver=0x6698e0, e=0x7fffb1cf9e80)
    at kernel/qapplication.cpp:2636
#27 0x00002ac8fa355d69 in QApplication::notify (this=0x7fffb1cfa310, 
    receiver=0x7140430, e=0x7fffb1cf9e80) at kernel/qapplication.cpp:2393
#28 0x00002ac8f9d42b38 in KApplication::notify (this=0x7fffb1cfa310, 
    receiver=0x7140430, event=0x7fffb1cf9e80) at ./kdecore/kapplication.cpp:552
#29 0x00002ac8f9cd8f59 in KAccelEventHandler::x11Event (
    this=<value optimized out>, pEvent=<value optimized out>)
    at /usr/lib/qt3/include/qapplication.h:520
#30 0x00002ac8f9d369b8 in KApplication::x11EventFilter (this=0x7fffb1cfa310, 
    _event=0x7fffb1cfa130) at ./kdecore/kapplication.cpp:1658
#31 0x00002ac8fa2ed297 in qt_x11EventFilter (ev=0x7fffb1cfa130)
    at kernel/qapplication_x11.cpp:388
#32 0x00002ac8fa2fba49 in QApplication::x11ProcessEvent (this=0x7fffb1cfa310, 
    event=0x7fffb1cfa130) at kernel/qapplication_x11.cpp:3344
#33 0x00002ac8fa30b25f in QEventLoop::processEvents (this=0x592fb0, flags=4)
    at kernel/qeventloop_x11.cpp:192
#34 0x00002ac8fa3697a1 in QEventLoop::enterLoop (this=0x59b5150)
    at kernel/qeventloop.cpp:198
#35 0x00002ac8fa36964a in QEventLoop::exec (this=0x59b5150)
    at kernel/qeventloop.cpp:145
#36 0x00000000004072f7 in main ()
Comment 1 Vadym Krevs 2006-06-21 17:29:00 UTC
Trivial to reproduce. Save the following as a cpp file. Then start KDevelop, close any open projects, File->Open and open the created file. Select everything from line 16 ("if (!blah)") until the end ("break;"), hit Ctrl-C, then move the cursor to the first line after the comments and hit Ctrl-V.

//
// C++ Implementation: eeee
//
// Description:
//
//
//
// Copyright: See COPYING file that comes with this distribution
//
//


if (foo)
else
bar;
                  if (!blah)
                        message(0, _TEXT("MESSAGE CODE 1"),
                             _TEXT("Error: "),
                             0, host);
                    else
                        message(0, _TEXT("MESSAGE CODE 2"),
                             _TEXT("Error: "),
                             0, user, host);
                    break;


Comment 2 Amilcar do Carmo Lucas 2006-06-21 17:39:35 UTC
Another KATE bug
Comment 3 Vadym Krevs 2006-06-21 17:44:48 UTC
Hmm, Kate itself does not crash on the sample case. Moreover, Kdevelop seems to crash far more frequently than Kate during basic editing operations.
Comment 4 Vadym Krevs 2006-06-21 18:31:30 UTC
Some output from valgrind - hope this helps.

==13389== Invalid read of size 2
==13389==    at 0x134DF333: KateTextLine::stringAtPos(unsigned, QString const&) const (katetextline.cpp:191)
==13389==    by 0x1355D136: KateCSmartIndent::calcContinue(KateDocCursor&, KateDocCursor&) (kateautoindent.cpp:894)
==13389==    by 0x1355E024: KateCSmartIndent::calcIndent(KateDocCursor&, bool) (kateautoindent.cpp:778)
==13389==    by 0x1355EB3B: KateCSmartIndent::processLine(KateDocCursor&) (kateautoindent.cpp:502)
==13389==    by 0x134F3C86: KateCSmartIndent::processSection(KateDocCursor const&, KateDocCursor const&) (kateautoindent.cpp:531)
==13389==    by 0x135812C9: KateDocument::paste(KateView*) (katedocument.cpp:3186)
==13389==    by 0x135A40F2: KateView::paste() (kateview.h:86)
==13389==    by 0x1358C076: KateView::qt_invoke(int, QUObject*) (kateview.moc:707)
==13389==    by 0x6002A8B: QObject::activate_signal(QConnectionList*, QUObject*) (qobject.cpp:2356)
==13389==    by 0x60037A2: QObject::activate_signal(int) (qobject.cpp:2325)
==13389==    by 0x551B7E7: KPasteTextAction::slotActivated() (kactionclasses.cpp:2371)
==13389==    by 0x55C030B: KPasteTextAction::qt_invoke(int, QUObject*) (kactionclasses.moc:1535)
==13389==  Address 0x2138D6D5E is not stack'd, malloc'd or (recently) free'd
KCrash: Application 'kdevelop' crashing...
==13389==
Comment 5 Jens Dagerbo 2006-06-21 18:32:26 UTC
The only part of the stack trace that references code inside KDevelop is frame #36 - the main() function(!).

I guess it's possible that the different ways the Kate view is embedded can have something to do with the different results in KDevelop and Kate (or maybe  something else entirely)
Comment 6 Andreas Kling 2006-06-21 18:50:11 UTC
Created attachment 16742 [details]
Potential fix

This seems to be the proper fix, could someone verify?
Comment 7 Andreas Kling 2006-06-21 19:29:12 UTC
*** Bug 129263 has been marked as a duplicate of this bug. ***
Comment 8 Stefan Nikolaus 2006-06-21 19:53:28 UTC
Confirmed with Kate.
The patch in #6 fixes this. Also a crash, which occurs when entering a doxygen comment: '/**' + <RETURN> 
Comment 9 Stefan Nikolaus 2006-06-21 19:57:31 UTC
But the 'duplicate' bug 129263 is NOT fixed with it alone.

The attached patch in 129263 does.
Comment 10 Andreas Kling 2006-06-21 20:15:56 UTC
SVN commit 553693 by kling:

Fixed a buffer overrun in stringAtPos() introduced in revision 549977.

BUG: 129580


 M  +3 -2      katetextline.cpp  


--- branches/KDE/3.5/kdelibs/kate/part/katetextline.cpp #553692:553693
@@ -179,15 +179,16 @@
 
 bool KateTextLine::stringAtPos(uint pos, const QString& match) const
 {
+  const uint len = m_text.length();
   const uint matchlen = match.length();
 
-  if ((pos+matchlen) > m_text.length())
+  if ((pos+matchlen) > len)
     return false;
 
   const QChar *unicode = m_text.unicode();
   const QChar *matchUnicode = match.unicode();
 
-  for (uint i=0; i < matchlen; i++)
+  for (uint i=0; i < matchlen && i < len; i++)
     if (unicode[i+pos] != matchUnicode[i])
       return false;
 
Comment 11 Dominik Haumann 2006-06-23 19:43:41 UTC
SVN commit 554328 by dhaumann:

* (pos > len) in case the uint pos was assigned a signed -1, pos+matchlen
  can overflow again which (pos+matchlen > len) does not catch; see bugs
  #129263 and #129580

The assert will probably catch when -1 was casted to uint (which should
of course not happen anymore).

CCBUG: 129580


 M  +5 -1      katetextline.cpp  


--- branches/KDE/3.5/kdelibs/kate/part/katetextline.cpp #554327:554328
@@ -185,10 +185,14 @@
   if ((pos+matchlen) > len)
     return false;
 
+  // (pos > len) in case the uint pos was assigned a signed -1, pos+matchlen can
+  // overflow again which (pos+matchlen > len) does not catch; see bugs #129263 and #129580
+  Q_ASSERT(pos < len);
+
   const QChar *unicode = m_text.unicode();
   const QChar *matchUnicode = match.unicode();
 
-  for (uint i=0; i < matchlen && i < len; i++)
+  for (uint i=0; i < matchlen; i++)
     if (unicode[i+pos] != matchUnicode[i])
       return false;
 
Comment 12 Dominik Haumann 2006-06-25 22:42:02 UTC
Just for info, also fixed in trunk.