Bug 426367

Summary: KIO::mostLocalUrl crashes on invalid URLs
Product: [Frameworks and Libraries] frameworks-kio Reporter: Nicolas Fella <nicolas.fella>
Component: generalAssignee: KIO Bugs <kio-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: a.samirh78, faure, kdelibs-bugs, nate
Priority: NOR    
Version: git master   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Nicolas Fella 2020-09-10 12:28:59 UTC
When passing an invalid QUrl, e.g. empty, to KIO::mostLocalUrl it will crash.

Before https://invent.kde.org/frameworks/kio/-/commit/38998e066aa711ec5da0d20817ff2f77d91b964b it would not crash, so it's a behavioural regression.

This results in KGet crashing when adding a new download

KDE Plasma Version: master
KDE Frameworks Version: master
Qt Version: 5.15
Comment 1 Nicolas Fella 2020-09-10 12:40:18 UTC
Application: KGet (kget), signal: Aborted
Content of s_kcrashErrorMessage: (null)
[New LWP 1439986]
[New LWP 1439987]
[New LWP 1439988]
[New LWP 1439989]
[New LWP 1439990]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x00007f040937246f in poll () from /usr/lib/libc.so.6
[Current thread is 1 (Thread 0x7f04057135c0 (LWP 1439984))]

Thread 6 (Thread 0x7f03f6a4a640 (LWP 1439990)):
#0  0x00007f04098206a2 in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
#1  0x00007f03fd72fe3c in ?? () from /usr/lib/dri/iris_dri.so
#2  0x00007f03fd72e838 in ?? () from /usr/lib/dri/iris_dri.so
#3  0x00007f040981a3e9 in start_thread () from /usr/lib/libpthread.so.0
#4  0x00007f040937d293 in clone () from /usr/lib/libc.so.6

Thread 5 (Thread 0x7f03eea4a640 (LWP 1439989)):
#0  0x00007f04098206a2 in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
#1  0x00007f03fd72fe3c in ?? () from /usr/lib/dri/iris_dri.so
#2  0x00007f03fd72e838 in ?? () from /usr/lib/dri/iris_dri.so
#3  0x00007f040981a3e9 in start_thread () from /usr/lib/libpthread.so.0
#4  0x00007f040937d293 in clone () from /usr/lib/libc.so.6

Thread 4 (Thread 0x7f03f724b640 (LWP 1439988)):
#0  0x00007f04098206a2 in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
#1  0x00007f03fd72fe3c in ?? () from /usr/lib/dri/iris_dri.so
#2  0x00007f03fd72e838 in ?? () from /usr/lib/dri/iris_dri.so
#3  0x00007f040981a3e9 in start_thread () from /usr/lib/libpthread.so.0
#4  0x00007f040937d293 in clone () from /usr/lib/libc.so.6

Thread 3 (Thread 0x7f03f7a4c640 (LWP 1439987)):
#0  0x00007f04098206a2 in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
#1  0x00007f03fd72fe3c in ?? () from /usr/lib/dri/iris_dri.so
#2  0x00007f03fd72e838 in ?? () from /usr/lib/dri/iris_dri.so
#3  0x00007f040981a3e9 in start_thread () from /usr/lib/libpthread.so.0
#4  0x00007f040937d293 in clone () from /usr/lib/libc.so.6

Thread 2 (Thread 0x7f0404cfa640 (LWP 1439986)):
#0  0x00007f040937246f in poll () from /usr/lib/libc.so.6
#1  0x00007f0405e35168 in ?? () from /usr/lib/libglib-2.0.so.0
#2  0x00007f0405de6221 in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#3  0x00007f0409be59ab in QEventDispatcherGlib::processEvents (this=0x7f0400000b60, flags=...) at kernel/qeventdispatcher_glib.cpp:425
#4  0x00007f0409b8ce2b in QEventLoop::exec (this=this@entry=0x7f0404cf9bf0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:141
#5  0x00007f04099ae0fe in QThread::exec (this=<optimized out>) at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#6  0x00007f040a05ea97 in QDBusConnectionManager::run (this=0x7f040a0ccd80 <(anonymous namespace)::Q_QGS__q_manager::innerFunction()::holder>) at qdbusconnection.cpp:179
#7  0x00007f04099af241 in QThreadPrivate::start (arg=0x7f040a0ccd80 <(anonymous namespace)::Q_QGS__q_manager::innerFunction()::holder>) at thread/qthread_unix.cpp:329
#8  0x00007f040981a3e9 in start_thread () from /usr/lib/libpthread.so.0
#9  0x00007f040937d293 in clone () from /usr/lib/libc.so.6

Thread 1 (Thread 0x7f04057135c0 (LWP 1439984)):
[KCrash Handler]
#5  0x00007f04092ba615 in raise () from /usr/lib/libc.so.6
#6  0x00007f04092a3862 in abort () from /usr/lib/libc.so.6
#7  0x00007f0409973c41 in qt_message_fatal (message=<synthetic pointer>..., context=...) at global/qlogging.cpp:1914
#8  QMessageLogger::fatal (this=this@entry=0x7ffdab32b258, msg=msg@entry=0x7f0409c6eee8 "ASSERT: \"%s\" in file %s, line %d") at global/qlogging.cpp:893
#9  0x00007f040997303a in qt_assert (assertion=<optimized out>, file=<optimized out>, line=<optimized out>) at ../../include/QtCore/../../src/corelib/global/qlogging.h:90
#10 0x00007f040baacad5 in KProtocolInfoFactory::findProtocol (this=0x7f040bb855e0 <(anonymous namespace)::Q_QGS_kProtocolInfoFactoryInstance::innerFunction()::holder>, protocol=...) at /home/nico/kde/src/kio/src/core/kprotocolinfofactory.cpp:62
#11 0x00007f040baabe99 in KProtocolInfo::protocolClass (_protocol=...) at /home/nico/kde/src/kio/src/core/kprotocolinfo.cpp:332
#12 0x00007f040ba6b1f6 in KIO::mostLocalUrl (url=..., flags=...) at /home/nico/kde/src/kio/src/core/statjob.cpp:218
#13 0x00007f040c4ec57a in mostLocalUrl (url=...) at /home/nico/kde/src/kget/core/mostlocalurl.cpp:39
#14 0x00005605acb1f5cd in NewTransferDialog::checkInput (this=0x5605ae285e10) at /home/nico/kde/src/kget/ui/newtransferdialog.cpp:300
#15 0x00005605acaef254 in NewTransferDialog::qt_static_metacall (_o=0x5605ae285e10, _c=QMetaObject::InvokeMetaMethod, _id=2, _a=0x7ffdab32b690) at kget_autogen/UYX5XTB5RZ/moc_newtransferdialog.cpp:86
#16 0x00007f0409bc4a50 in doActivate<false> (sender=0x5605ae339430, signal_index=3, argv=argv@entry=0x7ffdab32b690) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395
#17 0x00007f0409bbdd70 in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7f0409e5d260 <QTimer::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffdab32b690) at kernel/qobject.cpp:3946
#18 0x00007f0409bc892a in QTimer::timeout (this=<optimized out>, _t1=...) at .moc/moc_qtimer.cpp:205
#19 0x00007f0409bba39f in QObject::event (this=0x5605ae339430, e=0x7ffdab32b800) at kernel/qobject.cpp:1291
#20 0x00007f040a95311f in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x5605ae339430, e=0x7ffdab32b800) at kernel/qapplication.cpp:3630
#21 0x00007f0409b8e46a in QCoreApplication::notifyInternal2 (receiver=0x5605ae339430, event=0x7ffdab32b800) at ../../include/QtCore/5.15.1/QtCore/private/../../../../../src/corelib/thread/qthread_p.h:325
#22 0x00007f0409be4d53 in QTimerInfoList::activateTimers (this=0x5605ade79810) at kernel/qtimerinfo_unix.cpp:643
#23 0x00007f0409be55d4 in timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:183
#24 0x00007f0405de743c in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#25 0x00007f0405e351d9 in ?? () from /usr/lib/libglib-2.0.so.0
#26 0x00007f0405de6221 in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#27 0x00007f0409be598f in QEventDispatcherGlib::processEvents (this=0x5605adeb2430, flags=...) at kernel/qeventdispatcher_glib.cpp:423
#28 0x00007f0409b8ce2b in QEventLoop::exec (this=this@entry=0x7ffdab32ba40, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:141
#29 0x00007f0409b950a0 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#30 0x00005605acb92e1c in main (argc=1, argv=0x7ffdab32bca8) at /home/nico/kde/src/kget/main.cpp:186
[Inferior 1 (process 1439984) detached]
Comment 2 Ahmad Samir 2020-09-10 13:11:50 UTC
Indeed, we are hitting "Q_ASSERT(!protocol.isEmpty());", so we should return early in mostLocalUrl if the url is invalid or empty.
Comment 3 Ahmad Samir 2020-09-10 13:15:22 UTC
On second thought, kget should check the url before passing it to kio... I'll look into kget too.
Comment 4 Bug Janitor Service 2020-09-10 15:21:48 UTC
A possibly relevant merge request was started @ https://invent.kde.org/frameworks/kio/-/merge_requests/126
Comment 5 David Faure 2020-09-10 18:24:24 UTC
Agreed, both should be fixed. KIO should warn, KGet should avoid calling creating a job for nothing.
Comment 6 Ahmad Samir 2020-09-11 10:03:48 UTC
Git commit 6edec1f4907bae55684f61d38edd5376265ce538 by Ahmad Samir.
Committed on 11/09/2020 at 09:50.
Pushed by dfaure into branch 'master'.

StatJob: cancel job if url is invalid

This fixes an assert in KProtocolInfoFactory::findProtocol, which was
checking if protocl is empty.

Also it makes sense to not spend resources stat'ing an invalid url, (it's
probably more efficient if the code that's creating a StatJob, first checks
that the url is valid).

Add more log message explaining why a stat job is cancelled; per dfaure's
advice use a separate method with early returns to do that.

M  +21   -1    src/core/statjob.cpp

https://invent.kde.org/frameworks/kio/commit/6edec1f4907bae55684f61d38edd5376265ce538