Bug 303390 - Konsole crashes when selecting invalid unicode character.
Summary: Konsole crashes when selecting invalid unicode character.
Status: RESOLVED FIXED
Alias: None
Product: konsole
Classification: Applications
Component: general (show other bugs)
Version: 2.8.3
Platform: Gentoo Packages Linux
: NOR crash
Target Milestone: ---
Assignee: Konsole Developer
URL:
Keywords: reproducible
Depends on:
Blocks:
 
Reported: 2012-07-11 21:47 UTC by Thomas Lindroth
Modified: 2012-07-20 03:22 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In: 4.8.5


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Lindroth 2012-07-11 21:47:35 UTC
Konsole crashes when I try to select a line of text with an invalid unicode character. The text is japanese and can be printed by running
echo "44Kt44KZ44Oj44OrCg==" | base64 -d
It should look like キャル with the invalid character between キ and ャ.

It only crash when the line is selected back to front. Selecting the entire line or from front to back works fine.

I'm using the font called Console from console8x16.pcf.gz but it's only a bitmap font for ascii. It looks like Konsole is falling back to using Arial Unicode for the rest.

Konsole will freeze and use all available cpu for about 15 sec before the crash. I get no useful info from the backtrace. This is the error that is printed.
Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
KCrash: Application 'konsole' crashing...
KCrash: Attempting to start /usr/lib64/kde4/libexec/drkonqi from kdeinit

Here is the output from the crash handler.
Application: Konsole (konsole), signal: Aborted
[Current thread is 1 (Thread 0x7fd774575760 (LWP 10258))]

Thread 3 (Thread 0x7fd761556700 (LWP 10259)):
#0  0x00007fd773eda963 in poll () from /lib64/libc.so.6
#1  0x00007fd76de98406 in g_main_context_iterate.isra.23 () from /usr/lib64/libglib-2.0.so.0
#2  0x00007fd76de98534 in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
#3  0x00007fd772a4c96f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#4  0x00007fd772a1cad2 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#5  0x00007fd772a1cd27 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#6  0x00007fd77291de97 in QThread::exec() () from /usr/lib64/qt4/libQtCore.so.4
#7  0x00007fd7729fca8f in QInotifyFileSystemWatcherEngine::run() () from /usr/lib64/qt4/libQtCore.so.4
#8  0x00007fd772920e9b in QThreadPrivate::start(void*) () from /usr/lib64/qt4/libQtCore.so.4
#9  0x00007fd77268ae2c in start_thread () from /lib64/libpthread.so.0
#10 0x00007fd773ee34fd in clone () from /lib64/libc.so.6

Thread 2 (Thread 0x7fd760770700 (LWP 10261)):
#0  0x00007fd773edcf73 in select () from /lib64/libc.so.6
#1  0x00007fd7729faf41 in QProcessManager::run() () from /usr/lib64/qt4/libQtCore.so.4
#2  0x00007fd772920e9b in QThreadPrivate::start(void*) () from /usr/lib64/qt4/libQtCore.so.4
#3  0x00007fd77268ae2c in start_thread () from /lib64/libpthread.so.0
#4  0x00007fd773ee34fd in clone () from /lib64/libc.so.6

Thread 1 (Thread 0x7fd774575760 (LWP 10258)):
[KCrash Handler]
#6  0x00007fd773e40b35 in raise () from /lib64/libc.so.6
#7  0x00007fd773e41fab in abort () from /lib64/libc.so.6
#8  0x00007fd7717862bd in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/libstdc++.so.6
#9  0x00007fd771784476 in __cxxabiv1::__terminate(void (*)()) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/libstdc++.so.6
#10 0x00007fd7717844a3 in std::terminate() () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/libstdc++.so.6
#11 0x00007fd7717845e6 in __cxa_rethrow () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/libstdc++.so.6
#12 0x00007fd772a1cf9f in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#13 0x00007fd772a21835 in QCoreApplication::exec() () from /usr/lib64/qt4/libQtCore.so.4
#14 0x00007fd7741a8032 in kdemain () from /usr/lib64/libkdeinit4_konsole.so
#15 0x00007fd773e2d3dd in __libc_start_main () from /lib64/libc.so.6
#16 0x0000000000400791 in _start ()

I can recompile Qt with debug symbols if that would help.

Konsole is 2.8.3, qt 4.8.1

Reproducible: Always
Comment 1 Jekyll Wu 2012-07-11 22:22:51 UTC
Thanks for the report!

I can reproduce it using 2.8.3 and 2.9.999. 

No need to recompile your Qt :)
Comment 2 Kurt Hindenburg 2012-07-12 02:17:06 UTC
That's nice... on MacOSX use base64 -D


konsole(99607,0x7fff7acd8960) malloc: *** mmap(size=18446744071562072064) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.

terminate called throwing an exception
Program received signal SIGABRT, Aborted.
0x00007fff905fdce2 in __pthread_kill ()
(gdb) 
(gdb) 
(gdb) 
(gdb) bt
#0  0x00007fff905fdce2 in __pthread_kill ()
#1  0x00007fff918eb7d2 in pthread_kill ()
#2  0x00007fff918dca7a in abort ()
#3  0x00007fff956ce7bc in abort_message ()
#4  0x00007fff956cbfcf in default_terminate ()
#5  0x00007fff8c2ac1cd in _objc_terminate ()
#6  0x00007fff956cc001 in safe_handler_caller ()
#7  0x00007fff956cc05c in std::terminate ()
#8  0x00007fff956cd1e9 in __cxa_rethrow ()
#9  0x0000000101319f1d in QEventLoop::exec ()
#10 0x000000010131d163 in QCoreApplication::exec ()
#11 0x0000000100012ada in kdemain (argc=<value temporarily unavailable, due to optimizations>, 
    argv=<value temporarily unavailable, due to optimizations>)
    at /Volumes/OWC500GB/Projects/KDE/kde4/trunk/src/kde/kde-baseapps/konsole/src/main.cpp:85
#12 0x0000000100004ee4 in start ()
Comment 3 Kurt Hindenburg 2012-07-12 02:43:55 UTC
The loop at http://lxr.kde.org/source/kde/kde-baseapps/konsole/src/TerminalCharacterDecoder.cpp#110

txs to PovAddict on IRC
Comment 4 Kurt Hindenburg 2012-07-12 13:28:15 UTC
Git commit 5ae5bc5019ec67df0846b2b317c02535bce5870f by Kurt Hindenburg.
Committed on 12/07/2012 at 15:25.
Pushed by hindenburg into branch 'master'.

prevent crashing when selecting invalid unicode character.

Konsole goes into an infinite loop and will eventually crash due to
memory.  On an invalid unicode char the width is 0 so the for loop never
exits.
This should prevent the crashes; not sure if there is a better way.

M  +7    -1    src/TerminalCharacterDecoder.cpp

http://commits.kde.org/konsole/5ae5bc5019ec67df0846b2b317c02535bce5870f
Comment 5 Kurt Hindenburg 2012-07-14 22:25:24 UTC
Git commit f04bd15bbe15bee12c33c12aa252d3c4df8b9984 by Kurt Hindenburg.
Committed on 12/07/2012 at 15:25.
Pushed by hindenburg into branch 'KDE/4.8'.

prevent crashing when selecting invalid unicode character.

Konsole goes into an infinite loop and will eventually crash due to
memory.  On an invalid unicode char the width is 0 so the for loop never
exits.
This should prevent the crashes; not sure if there is a better way.
(cherry picked from commit 5ae5bc5019ec67df0846b2b317c02535bce5870f)

M  +7    -1    src/TerminalCharacterDecoder.cpp

http://commits.kde.org/konsole/f04bd15bbe15bee12c33c12aa252d3c4df8b9984
Comment 6 Francesco Cecconi 2012-07-14 23:17:58 UTC
Another option could be to use qMax for increment i. 

if (chars) {
 const QString s = QString::fromUtf16(chars, extendedCharLength);
 plainText.append(s);
 i += qMax(1, string_width(s));
}
Comment 7 Kurt Hindenburg 2012-07-20 02:45:42 UTC
Git commit 69b53c00ae53d6a066292d3f1a96599a75eff618 by Kurt Hindenburg.
Committed on 20/07/2012 at 04:34.
Pushed by hindenburg into branch 'master'.

prevent crashing when selecting invalid unicode character.

Konsole goes into an infinite loop and will eventually crash due to
memory.  On an invalid unicode char the width is 0 so the for loop never
exits.
A better patch by Francesco Cecconi <francesco.cecconi@gmail.com>

M  +1    -6    src/TerminalCharacterDecoder.cpp

http://commits.kde.org/konsole/69b53c00ae53d6a066292d3f1a96599a75eff618
Comment 8 Kurt Hindenburg 2012-07-20 03:03:29 UTC
Git commit 4ce0647eaae3cc1e486955232e9dc52c43538233 by Kurt Hindenburg.
Committed on 20/07/2012 at 04:34.
Pushed by hindenburg into branch 'KDE/4.8'.

prevent crashing when selecting invalid unicode character.

Konsole goes into an infinite loop and will eventually crash due to
memory.  On an invalid unicode char the width is 0 so the for loop never
exits.
A better patch by Francesco Cecconi <francesco.cecconi@gmail.com>
(cherry picked from commit 69b53c00ae53d6a066292d3f1a96599a75eff618)

M  +1    -6    src/TerminalCharacterDecoder.cpp

http://commits.kde.org/konsole/4ce0647eaae3cc1e486955232e9dc52c43538233
Comment 9 Jekyll Wu 2012-07-20 03:22:50 UTC
Git commit 6a13493a0b14956b5ef332653f71551016756d6e by Jekyll Wu.
Committed on 20/07/2012 at 04:56.
Pushed by jekyllwu into branch 'KDE/4.9'.

prevent crashing when selecting invalid unicode character.

Konsole goes into an infinite loop and will eventually crash due to
memory.  On an invalid unicode char the width is 0 so the for loop never
exits.
A better patch by Francesco Cecconi <francesco.cecconi@gmail.com>
(cherry picked from commit 69b53c00ae53d6a066292d3f1a96599a75eff618)

M  +1    -1    src/TerminalCharacterDecoder.cpp

http://commits.kde.org/konsole/6a13493a0b14956b5ef332653f71551016756d6e