Bug 305573

Summary: KMyMoney instantly crashes upon assigning "Input Column" numbers during CSV file import
Product: [Applications] kmymoney Reporter: at
Component: generalAssignee: KMyMoney Devel Mailing List <kmymoney-devel>
Status: RESOLVED FIXED    
Severity: crash CC: agander93, ostroffjh
Priority: NOR    
Version: 4.6.2   
Target Milestone: ---   
Platform: Fedora RPMs   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: A sample CSV file, including the header and a single line of data.

Description at 2012-08-22 04:06:41 UTC
Application: kmymoney (4.6.2)
KDE Platform Version: 4.8.5 (4.8.5)
Qt Version: 4.8.2
Operating System: Linux 3.5.1-1.fc17.x86_64 x86_64
Distribution (Platform): Fedora RPMs

-- Information about the crash:
- What I was doing when the application crashed:

1) Choose to 'Import CSV' 2) Open target CSV file 3) Assign ANY "Input Column" number, by merely clicking on a number in the drop down menu = instant crash.

The crash can be reproduced every time.

-- Backtrace:
Application: KMyMoney (kmymoney), signal: Segmentation fault
Using host libthread_db library "/lib64/libthread_db.so.1".
[Current thread is 1 (Thread 0x7f52f1ad5880 (LWP 17516))]

Thread 2 (Thread 0x7f52ddd0e700 (LWP 17527)):
#0  0x0000003d138e827f in poll () from /lib64/libc.so.6
#1  0x0000003d15847964 in g_main_context_poll (n_fds=1, fds=0x7f52d8002c20, timeout=-1, context=0x7f52d80009a0, priority=<optimized out>) at gmain.c:3440
#2  g_main_context_iterate (context=context@entry=0x7f52d80009a0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3141
#3  0x0000003d15847a84 in g_main_context_iteration (context=0x7f52d80009a0, may_block=1) at gmain.c:3207
#4  0x0000003d1f1a4506 in QEventDispatcherGlib::processEvents (this=0x7f52d80008c0, flags=...) at kernel/qeventdispatcher_glib.cpp:426
#5  0x0000003d1f17513f in QEventLoop::processEvents (this=this@entry=0x7f52ddd0dce0, flags=...) at kernel/qeventloop.cpp:149
#6  0x0000003d1f1753c8 in QEventLoop::exec (this=0x7f52ddd0dce0, flags=...) at kernel/qeventloop.cpp:204
#7  0x0000003d1f078650 in QThread::exec (this=<optimized out>) at thread/qthread.cpp:501
#8  0x0000003d1f157618 in QDnotifySignalThread::run (this=0x2c3b700) at io/qfilesystemwatcher_dnotify.cpp:179
#9  0x0000003d1f07b5eb in QThreadPrivate::start (arg=0x2c3b700) at thread/qthread_unix.cpp:307
#10 0x0000003d14407d14 in start_thread () from /lib64/libpthread.so.0
#11 0x0000003d138f0d2d in clone () from /lib64/libc.so.6

Thread 1 (Thread 0x7f52f1ad5880 (LWP 17516)):
[KCrash Handler]
#6  0x0000003d1f0c0466 in QString::operator== (this=0x46d5f80, other=...) at tools/qstring.cpp:2192
#7  0x00007f52e226702d in CsvImporterDlg::validateColumn (this=this@entry=0x46d5b50, col=@0x7fff56189f6c: 9, type=...) at /usr/src/debug/kmymoney-4.6.2/kmymoney/plugins/csvimport/csvimporterdlg.cpp:259
#8  0x00007f52e2267220 in CsvImporterDlg::numberColumnSelected (this=0x46d5b50, col=9) at /usr/src/debug/kmymoney-4.6.2/kmymoney/plugins/csvimport/csvimporterdlg.cpp:452
#9  0x0000003d1f18cb9f in QMetaObject::activate (sender=0x22e3800, m=<optimized out>, local_signal_index=<optimized out>, argv=0x7fff5618a0d0) at kernel/qobject.cpp:3547
#10 0x0000003d2219b851 in QComboBox::currentIndexChanged (this=this@entry=0x22e3800, _t1=9) at .moc/release-shared/moc_qcombobox.cpp:315
#11 0x0000003d2219b8b7 in QComboBoxPrivate::_q_emitCurrentIndexChanged (this=this@entry=0x4585280, index=...) at widgets/qcombobox.cpp:1278
#12 0x0000003d2219bac0 in QComboBoxPrivate::setCurrentIndex (this=this@entry=0x4585280, mi=...) at widgets/qcombobox.cpp:2046
#13 0x0000003d2219c754 in QComboBoxPrivate::_q_itemSelected (this=0x4585280, item=...) at widgets/qcombobox.cpp:1247
#14 0x0000003d1f18cb9f in QMetaObject::activate (sender=0x4f13ba0, m=<optimized out>, local_signal_index=<optimized out>, argv=0x7fff5618a340) at kernel/qobject.cpp:3547
#15 0x0000003d2242fd42 in QComboBoxPrivateContainer::itemSelected (this=<optimized out>, _t1=...) at .moc/release-shared/moc_qcombobox_p.cpp:252
#16 0x0000003d22196dd7 in QComboBoxPrivateContainer::eventFilter (this=0x4f13ba0, o=0x8350830, e=0x7fff5618aa90) at widgets/qcombobox.cpp:691
#17 0x0000003d1f176556 in QCoreApplicationPrivate::sendThroughObjectEventFilters (this=<optimized out>, receiver=0x8350830, event=0x7fff5618aa90) at kernel/qcoreapplication.cpp:1025
#18 0x0000003d21dca34c in QApplicationPrivate::notify_helper (this=this@entry=0x14276a0, receiver=receiver@entry=0x8350830, e=e@entry=0x7fff5618aa90) at kernel/qapplication.cpp:4547
#19 0x0000003d21dcf05b in QApplication::notify (this=<optimized out>, receiver=0x8350830, e=0x7fff5618aa90) at kernel/qapplication.cpp:4094
#20 0x0000003d22c462b6 in KApplication::notify (this=0x141a120, receiver=0x8350830, event=0x7fff5618aa90) at /usr/src/debug/kdelibs-4.8.5/kdeui/kernel/kapplication.cpp:311
#21 0x0000003d1f1763ee in QCoreApplication::notifyInternal (this=0x141a120, receiver=0x8350830, event=0x7fff5618aa90) at kernel/qcoreapplication.cpp:915
#22 0x0000003d21dcb1bb in sendEvent (event=<optimized out>, receiver=<optimized out>) at ../../src/corelib/kernel/qcoreapplication.h:231
#23 QApplicationPrivate::sendMouseEvent (receiver=0x8350830, event=0x7fff5618aa90, alienWidget=0x8350830, nativeWidget=0x4f13ba0, buttonDown=0x3d2289dd68, lastMouseReceiver=..., spontaneous=true) at kernel/qapplication.cpp:3162
#24 0x0000003d21e4575c in QETWidget::translateMouseEvent (this=this@entry=0x4f13ba0, event=event@entry=0x7fff5618b200) at kernel/qapplication_x11.cpp:4457
#25 0x0000003d21e44621 in QApplication::x11ProcessEvent (this=0x141a120, event=0x7fff5618b200) at kernel/qapplication_x11.cpp:3646
#26 0x0000003d21e6a60c in x11EventSourceDispatch (s=s@entry=0x1427a10, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:148
#27 0x0000003d15847695 in g_main_dispatch (context=0x1426130) at gmain.c:2539
#28 g_main_context_dispatch (context=context@entry=0x1426130) at gmain.c:3075
#29 0x0000003d158479c8 in g_main_context_iterate (context=context@entry=0x1426130, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3146
#30 0x0000003d15847a84 in g_main_context_iteration (context=0x1426130, may_block=1) at gmain.c:3207
#31 0x0000003d1f1a44e6 in QEventDispatcherGlib::processEvents (this=0x13f7770, flags=...) at kernel/qeventdispatcher_glib.cpp:424
#32 0x0000003d21e6a2ee in QGuiEventDispatcherGlib::processEvents (this=<optimized out>, flags=...) at kernel/qguieventdispatcher_glib.cpp:207
#33 0x0000003d1f17513f in QEventLoop::processEvents (this=this@entry=0x7fff5618b5d0, flags=...) at kernel/qeventloop.cpp:149
#34 0x0000003d1f1753c8 in QEventLoop::exec (this=0x7fff5618b5d0, flags=...) at kernel/qeventloop.cpp:204
#35 0x0000003d1f17a1b8 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1187
#36 0x0000000000457d46 in runKMyMoney (splash=splash@entry=0x157f670, a=0x141a120) at /usr/src/debug/kmymoney-4.6.2/kmymoney/main.cpp:282
#37 0x000000000045650f in main (argc=1, argv=0x7fff5618c0c8) at /usr/src/debug/kmymoney-4.6.2/kmymoney/main.cpp:181

Reported using DrKonqi
Comment 1 allan 2012-08-22 09:51:32 UTC
(In reply to comment #0)
> Application: kmymoney (4.6.2)
> KDE Platform Version: 4.8.5 (4.8.5)
> Qt Version: 4.8.2
> Operating System: Linux 3.5.1-1.fc17.x86_64 x86_64
> Distribution (Platform): Fedora RPMs
> 
> -- Information about the crash:
> - What I was doing when the application crashed:
> 
> 1) Choose to 'Import CSV' 2) Open target CSV file 3) Assign ANY "Input
> Column" number, by merely clicking on a number in the drop down menu =
> instant crash.
> 
> The crash can be reproduced every time.
> 
> -- Backtrace:
> Application: KMyMoney (kmymoney), signal: Segmentation fault
> Using host libthread_db library "/lib64/libthread_db.so.1".
> [Current thread is 1 (Thread 0x7f52f1ad5880 (LWP 17516))]
> 
> Thread 1 (Thread 0x7f52f1ad5880 (LWP 17516)):
> [KCrash Handler]
> #6  0x0000003d1f0c0466 in QString::operator== (this=0x46d5f80, other=...) at
> tools/qstring.cpp:2192
> #7  0x00007f52e226702d in CsvImporterDlg::validateColumn
> (this=this@entry=0x46d5b50, col=@0x7fff56189f6c: 9, type=...) at
> /usr/src/debug/kmymoney-4.6.2/kmymoney/plugins/csvimport/csvimporterdlg.cpp:
> 259
> #8  0x00007f52e2267220 in CsvImporterDlg::numberColumnSelected
> (this=0x46d5b50, col=9) at
> /usr/src/debug/kmymoney-4.6.2/kmymoney/plugins/csvimport/csvimporterdlg.cpp:
> 452

Obviously, this does not happen normally, so it may be that there is something in your file format that is not being handled correctly.  You do not need to send the whole file if it is large, as long as the line on which it chokes is included, if you you can determine this.  Might one of the lines have fewer cells than the other lines?

Is it possible to provide a copy of your file with any private data disguised, as long as the format is not changed.

Are you using the stock Fedora package, or have you compiled from source?
Comment 2 at 2012-08-22 21:51:59 UTC
Created attachment 73403 [details]
A sample CSV file, including the header and a single line of data.
Comment 3 at 2012-08-22 21:59:04 UTC
The data I am trying to import is a typical PayPal history download (in CSV format). The file I have attached is an example of their CSV format. I have edited it to have only one row of data and, plus the header row. This file also causes an instant crash upon trying to assign and "Input Column".

I am using stock Fedora 17 x86_64. Although, I have also reproduced the problem on stock Fedora 15 x86_64, as well.
Comment 4 allan 2012-08-22 22:56:59 UTC
(In reply to comment #3)
> The data I am trying to import is a typical PayPal history download (in CSV
> format). The file I have attached is an example of their CSV format. I have
> edited it to have only one row of data and, plus the header row. This file
> also causes an instant crash upon trying to assign and "Input Column".
> 
> I am using stock Fedora 17 x86_64. Although, I have also reproduced the
> problem on stock Fedora 15 x86_64, as well.

Confirmed!  That sets a world record for the greatest number of columns,  45.  I'd only allowed for 25, which itself is greater than I've seen.  An array is going out-of-bounds.  Need to be cleverer.

It may take a while for the distros to pick up the fix, I'm afraid, unless you are able to compile from source?
Comment 5 allan 2012-08-22 23:11:41 UTC
Temporarily, I've changed the default limit to 50 columns, and your file now imports.  How long before a 51-column file appears?  I'll need to look more closely.
Comment 6 Jack 2012-08-22 23:16:10 UTC
Even inf you can't make the number of columns completely dynamic, can you at least check the number of columns and issue an error, rather than crashing?
Comment 7 allan 2012-08-22 23:37:27 UTC
(In reply to comment #6)
> Even inf you can't make the number of columns completely dynamic, can you at
> least check the number of columns and issue an error, rather than crashing?

I'd sooner not have to do anything major, but I'm aiming for dynamic.  An error message doesn't do much for the user's import, but....we'll see.
Comment 8 Thomas Baumgart 2012-08-23 18:17:29 UTC
Please try to use any of the Qt container classes. it should help you with the dynamics a lot. QVector sounds like a good candidate. See http://qt-project.org/doc/qt-4.8/containers.html for an overview.
Comment 9 allan 2012-08-27 12:47:41 UTC
(In reply to comment #8)
> Please try to use any of the Qt container classes. it should help you with
> the dynamics a lot. QVector sounds like a good candidate. See
> http://qt-project.org/doc/qt-4.8/containers.html for an overview.

I think the reference to 'dynamic' was perhaps a bit misleading.  What was being referred to was to replace the original fixed array size with one depending on the file size.  The actual array itself requires little manipulation, no insertions or deletions, apart from when a ne file is loaded.

I looked at QVector and didn't see anything there that was not provided by replacing the QString array with a QStringList.

The major problem was in the relocation of the 'setting sizes' code  away from the ctor to the readFile routine.  This in turn lead to a number of connect problems.

All now seems to be well, both for banking and investments.  The changes are not insignificant - 
 kmymoney/plugins/csvimport/csvdialog.cpp        |  308 ++++++++++++-----------
 kmymoney/plugins/csvimport/csvdialog.h          |    5 +-
 kmymoney/plugins/csvimport/investmentdlg.cpp    |   32 ---
 kmymoney/plugins/csvimport/investmentdlg.h      |    7 -
 kmymoney/plugins/csvimport/investprocessing.cpp |  231 +++++++++++-------
 kmymoney/plugins/csvimport/investprocessing.h   |    5 +-
 6 files changed, 316 insertions(+), 272 deletions(-)

So, do I need to go through reviewboard?  At the moment, the fixes apply to the stable release only.  The reason is that I am some way through a biggish tidy-up of the development version, and am intending to include the bug fix in with them.
Comment 10 allan 2012-08-27 13:19:52 UTC
PS
Bearing in mind what Cristian has said about not making reviewboard code too large, it might not be such a good idea to merge these changes in with another biggish set.
So, should I instead apply them to the HEAD?  This might also give them a bit more visibility too.
Then. backport to stable.
Comment 11 Thomas Baumgart 2012-08-28 11:29:33 UTC
Please try to seperate the two actions into two different git change sets (commits) so that we can  backport it using cherry-picking.
Comment 12 allan 2012-08-28 12:30:09 UTC
(In reply to comment #11)
> Please try to seperate the two actions into two different git change sets
> (commits) so that we can  backport it using cherry-picking.

I've now applied the changes locally to HEAD, and I'll do the commit later.
Comment 13 allan 2012-08-28 16:13:38 UTC
Git commit a83c75715d3e5ba2037cd2aa1b38a97f043b9a40 by Allan Anderson.
Committed on 28/08/2012 at 12:27.
Pushed by allananderson into branch 'master'.
Fix handling of multiple columns

M  +160  -130  kmymoney/plugins/csvimport/csvdialog.cpp
M  +2    -3    kmymoney/plugins/csvimport/csvdialog.h
M  +0    -32   kmymoney/plugins/csvimport/investmentdlg.cpp
M  +0    -9    kmymoney/plugins/csvimport/investmentdlg.h
M  +145  -87   kmymoney/plugins/csvimport/investprocessing.cpp
M  +2    -4    kmymoney/plugins/csvimport/investprocessing.h
M  +0    -1    kmymoney/plugins/csvimport/redefinedlg.cpp
M  +0    -2    kmymoney/plugins/csvimport/redefinedlg.h

http://commits.kde.org/kmymoney/a83c75715d3e5ba2037cd2aa1b38a97f043b9a40