Bug 393496 - assert in KProtocolInfoFactory::findProtocol() crashes Konqueror with invalid URLs
Summary: assert in KProtocolInfoFactory::findProtocol() crashes Konqueror with invalid...
Status: RESOLVED FIXED
Alias: None
Product: konqueror
Classification: Applications
Component: general (show other bugs)
Version: Git
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: Konqueror Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-04-25 11:17 UTC by Jonathan Marten
Modified: 2020-12-26 15:23 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Marten 2018-04-25 11:17:20 UTC
https://phabricator.kde.org/D11013 introduced an assert in that function to detect invalid parameters passed to it.  This is reasonable, but the assert is hit if Konqueror is asked to show an invalid URL (on the command line or typed in the address bar) in at least two cases:

1.  An obviously invalid URL (debug output trimmed):

$ konqueror --part khtml 'help me'
konqueror(5939) handleCommandLine: args= ("help me")
konqueror(5939) KShortUriFilter::filterUri: "help me"
konqueror(5939) KUriSearchFilter::filterUri: "help me" : QUrl("") , type = 8
konqueror(5939) KAutoWebSearch::filterUri: "help me"
konqueror(5939) KonqMainWindow::openUrl: url= QUrl("error:/?error=105&errText=help me#help me") mimeType= "" _req= "[serviceName=khtml]" view= QObject(0x0)
konqueror(5939) KProtocolInfoFactory::findProtocol: Refilling KProtocolInfoFactory cache in the hope to find "error"
konqueror(5939) KonqMainWindow::openView: "text/html" QUrl("error:/?error=105&errText=help me#help me") childView= QObject(0x0) req: "[serviceName=khtml forceAutoEmbed]"
konqueror(5939) KonqFactory::createView: Trying to create view for "text/html" "khtml"
konqueror(5939) KonqFactory::createView: Found requested service "khtml"
konqueror(5939) KonqFactory::createView: Trying to open lib for requested service  "khtml"
konqueror(5939) KonqViewManager::doSetActivePart: KHTMLPart(0x5610457394d0) QUrl("")
konqueror(5939) KonqMainWindow::slotPartActivated: KHTMLPart(0x5610457394d0) "khtml"
konqueror(5939) KonqMainWindow::slotPartActivated: New current view konqueror(5939) KonqView::openUrl: url= QUrl("error:/?error=105&errText=help me#help me") locationBarURL= "error:/?error=105&errText=help me#help me"
konqueror(5939) unknown: ASSERT: "!protocol.isEmpty()" in file /ws/frameworks/tier3/kio/src/core/kprotocolinfofactory.cpp, line 74
KCrash: crashing... crashRecursionCounter = 2
KCrash: Application Name = konqueror path = /usr/kde5/bin pid = 5939
KCrash: Arguments: /usr/kde5/bin/konqueror --part khtml help me 
KCrash: Attempting to start /usr/kde5/lib64/libexec/drkonqi from kdeinit

[KCrash Handler]
#5  0x00007fce2cecd248 in raise () from /lib64/libc.so.6
#6  0x00007fce2cecef99 in abort () from /lib64/libc.so.6
#7  0x00007fce2e58e787 in QMessageLogger::fatal(char const*, ...) const () from /usr/lib64/libQt5Core.so.5
#8  0x00007fce2e5895d6 in qt_assert(char const*, char const*, int) () from /usr/lib64/libQt5Core.so.5
#9  0x00007fce3468847b in KProtocolInfoFactory::findProtocol (this=0x7fce349143c0 <(anonymous namespace)::Q_QGS_kProtocolInfoFactoryInstance::innerFunction()::holder>, protocol=...) at /ws/frameworks/tier3/kio/src/core/kprotocolinfofactory.cpp:74
#10 0x00007fce34683c09 in KProtocolInfo::protocolClass (_protocol=...) at /ws/frameworks/tier3/kio/src/core/kprotocolinfo.cpp:338
#11 0x00007fce34629ae8 in KIO::rawErrorDetail (errorCode=errorCode@entry=105, errorText=..., reqUrl=reqUrl@entry=0x56104568ce00) at /ws/frameworks/tier3/kio/src/core/job_error.cpp:331
#12 0x00007fce0e259ecc in KHTMLPart::htmlError (this=this@entry=0x5610457394d0, errorCode=errorCode@entry=105, text=..., reqUrl=...) at /ws/frameworks/tier3/khtml/src/khtml_part.cpp:1891
#13 0x00007fce0e25b1df in KHTMLPart::openUrl (this=0x5610457394d0, url=...) at /ws/frameworks/tier3/khtml/src/khtml_part.cpp:753
#14 0x00007fce35f4b795 in KonqView::openUrl (this=this@entry=0x5610456ce6c0, url=..., locationBarURL=..., nameFilter=..., tempFile=<optimized out>) at /ws/frameworks/applications/konqueror/src/konqview.cpp:227
#15 0x00007fce35f939c0 in KonqMainWindow::openView (this=this@entry=0x5610455d86d0, mimeType=..., _url=..., childView=0x5610456ce6c0, childView@entry=0x0, req=...) at /ws/frameworks/applications/konqueror/src/konqmainwindow.cpp:998
#16 0x00007fce35f94bdd in KonqMainWindow::openUrl (this=this@entry=0x5610455d86d0, _view=_view@entry=0x0, _url=..., _mimeType=..., _req=..., trustedSource=trustedSource@entry=false) at /ws/frameworks/applications/konqueror/src/konqmainwindow.cpp:716
#17 0x00007fce35fa8488 in KonqMainWindowFactory::createNewWindow (url=..., req=...) at /ws/frameworks/applications/konqueror/src/konqmainwindowfactory.cpp:78
#18 0x00007fce35fc754f in handleCommandLine (parser=..., workingDirectory=..., ret=ret@entry=0x7ffe7e7cb8e8) at /ws/frameworks/applications/konqueror/src/konqmain.cpp:143
#19 0x00007fce35fcba9d in kdemain (argc=<optimized out>, argv=<optimized out>) at /ws/frameworks/applications/konqueror/src/konqmain.cpp:270
#20 0x00007fce2ceb8571 in __libc_start_main () from /lib64/libc.so.6
#21 0x0000561044bfdbda in _start ()

2.  An unknown protocol (this time happening in a plugin, but only with the WebKit part):

$ konqueror --part webkitpart 'zzzz:/'
konqueror(5999) handleCommandLine: args= ("zzzz:/")
konqueror(5999) KShortUriFilter::filterUri: "zzzz:/"
konqueror(5999) KShortUriFilter::filterUri: url= QUrl("zzzz:/") cmd= "zzzz:/" isMalformed= false
konqueror(5999) KShortUriFilter::filterUri: path = ""  isLocalFullPath= false  exists= false  url= QUrl("zzzz:/")
konqueror(5999) KShortUriFilter::filterUri: testing regexp for "ftp://"
konqueror(5999) KShortUriFilter::filterUri: testing regexp for "mailto:"
konqueror(5999) KUriSearchFilter::filterUri: "zzzz:/" : QUrl("zzzz:/") , type = 8
konqueror(5999) KProtocolInfoFactory::findProtocol: Refilling KProtocolInfoFactory cache in the hope to find "zzzz"
konqueror(5999) KProtocolInfoFactory::findProtocol: Refilling KProtocolInfoFactory cache in the hope to find "zzzz"
konqueror(5999) KAutoWebSearch::filterUri: "zzzz:/"
konqueror(5999) KonqMainWindow::openUrl: url= QUrl("error:/?error=105&errText=zzzz%3A%2F#zzzz:/") mimeType= "" _req= "[serviceName=webkitpart]" view= QObject(0x0)
konqueror(5999) KonqMainWindow::openView: "text/html" QUrl("error:/?error=105&errText=zzzz%3A%2F#zzzz:/") childView= QObject(0x0) req: "[serviceName=webkitpart forceAutoEmbed]"
konqueror(5999) KonqFactory::createView: Trying to create view for "text/html" "webkitpart"
konqueror(5999) KonqFactory::createView: "kwebkitpart"  : X-KDE-BrowserView-AllowAsDefault is valid :  false
konqueror(5999) KWebKitFactory::create: KonqFrame(0x560784b34d40) QObject(0x0)
konqueror(5999) KonqViewManager::doSetActivePart: KWebKitPart(0x560784ba5b30) QUrl("")
konqueror(5999) KonqMainWindow::slotPartActivated: KWebKitPart(0x560784ba5b30) "kwebkitpart"
konqueror(5999) KonqMainWindow::slotPartActivated: New current view KonqView(0x560784c0ed60)
konqueror(5999) KonqView::openUrl: url= QUrl("error:/?error=105&errText=zzzz%3A%2F#zzzz:/") locationBarURL= "error:/?error=105&errText=zzzz%3A%2F#zzzz:/"
konqueror(5999) KWebKitPart::openUrl: QUrl("error:/?error=105&errText=zzzz%3A%2F#zzzz:/")
konqueror(5999) unknown: ASSERT: "!protocol.isEmpty()" in file /ws/frameworks/tier3/kio/src/core/kprotocolinfofactory.cpp, line 74
KCrash: crashing... crashRecursionCounter = 2
KCrash: Application Name = konqueror path = /usr/kde5/bin pid = 5999
KCrash: Arguments: /usr/kde5/bin/konqueror --part webkitpart zzzz:/ 
KCrash: Attempting to start /usr/kde5/lib64/libexec/drkonqi from kdeinit

[KCrash Handler]
#6  0x00007f2c98ce6248 in raise () from /lib64/libc.so.6
#7  0x00007f2c98ce7f99 in abort () from /lib64/libc.so.6
#8  0x00007f2c9a3a7787 in QMessageLogger::fatal(char const*, ...) const () from /usr/lib64/libQt5Core.so.5
#9  0x00007f2c9a3a25d6 in qt_assert(char const*, char const*, int) () from /usr/lib64/libQt5Core.so.5
#10 0x00007f2ca04a147b in KProtocolInfoFactory::findProtocol (this=0x7f2ca072d3c0 <(anonymous namespace)::Q_QGS_kProtocolInfoFactoryInstance::innerFunction()::holder>, protocol=...) at /ws/frameworks/tier3/kio/src/core/kprotocolinfofactory.cpp:74
#11 0x00007f2ca049cc09 in KProtocolInfo::protocolClass (_protocol=...) at /ws/frameworks/tier3/kio/src/core/kprotocolinfo.cpp:338
#12 0x00007f2c333e3481 in Akregator::KonqFeedIcon::feedFound (this=0x560784b1b8b0) at /ws/frameworks/applications/konqueror/plugins/akregator/konqfeedicon.cpp:106
#13 0x00007f2c333e4500 in Akregator::KonqFeedIcon::addFeedIcon (this=0x560784b1b8b0) at /ws/frameworks/applications/konqueror/plugins/akregator/konqfeedicon.cpp:160
#14 0x00007f2c9a590c29 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#15 0x00007f2ca0d93302 in KParts::ReadOnlyPart::completed (this=this@entry=0x560784ba5b30, _t1=<optimized out>) at /ws/BUILD.keelhaul/tier3-kparts--frameworks-BUILD/src/KF5Parts_autogen/include/moc_readonlypart.cpp:248
#16 0x00007f2c7a89feef in KWebKitPart::slotLoadFinished (this=0x560784ba5b30, ok=<optimized out>) at /ws/frameworks/extragear/kwebkitpart/src/kwebkitpart.cpp:559
#17 0x00007f2c9a590c29 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#18 0x00007f2c7a638e32 in QWebView::loadFinished(bool) () from /usr/kde5/lib/libQt5WebKitWidgets.so.5
#19 0x00007f2c7a63a08c in QWebView::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) () from /usr/kde5/lib/libQt5WebKitWidgets.so.5
#20 0x00007f2c9a590c29 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#21 0x00007f2c7a62e072 in QWebPage::loadFinished(bool) () from /usr/kde5/lib/libQt5WebKitWidgets.so.5
#22 0x00007f2c7a62b8f1 in QWebFramePrivate::emitLoadFinished(bool, bool) () from /usr/kde5/lib/libQt5WebKitWidgets.so.5
#23 0x00007f2c77de1be7 in WebCore::FrameLoaderClientQt::dispatchDidFinishLoad() () from /usr/kde5/lib/libQt5WebKit.so.5
#24 0x00007f2c78e039c9 in WebCore::FrameLoader::checkLoadCompleteForThisFrame() () from /usr/kde5/lib/libQt5WebKit.so.5
#25 0x00007f2c78e03b0a in WebCore::FrameLoader::checkLoadComplete() () from /usr/kde5/lib/libQt5WebKit.so.5
#26 0x00007f2c78e03d08 in WebCore::FrameLoader::checkCompleted() [clone .part.323] () from /usr/kde5/lib/libQt5WebKit.so.5
#27 0x00007f2c78e702dd in WebCore::CachedResourceLoader::loadDone(WebCore::CachedResource*, bool) () from /usr/kde5/lib/libQt5WebKit.so.5
#28 0x00007f2c78e463cd in WebCore::SubresourceLoader::didFinishLoading(double) () from /usr/kde5/lib/libQt5WebKit.so.5
#29 0x00007f2c78e3b10a in WebCore::ResourceLoader::loadDataURL()::{lambda(WTF::Optional<WebCore::DataURLDecoder::Result>)#1}::operator()(WTF::Optional<WebCore::DataURLDecoder::Result>) const () from /usr/kde5/lib/libQt5WebKit.so.5
#30 0x00007f2c78e3fdcd in std::_Function_handler<void (WTF::Optional<WebCore::DataURLDecoder::Result>), WebCore::ResourceLoader::loadDataURL()::{lambda(WTF::Optional<WebCore::DataURLDecoder::Result>)#1}>::_M_invoke(std::_Any_data const&, WTF::Optional<WebCore::DataURLDecoder::Result>&&) () from /usr/kde5/lib/libQt5WebKit.so.5
#31 0x00007f2c7902aca3 in std::_Function_handler<void (), WebCore::DataURLDecoder::decode(WebCore::URL const&, WebCore::DataURLDecoder::ScheduleContext const&, std::function<void (WTF::Optional<WebCore::DataURLDecoder::Result>)>)::{lambda()#1}::operator()() const::{lambda()#1}>::_M_invoke(std::_Any_data const&) () from /usr/kde5/lib/libQt5WebKit.so.5
#32 0x00007f2c7870f738 in WTF::dispatchFunctionsFromMainThread() () from /usr/kde5/lib/libQt5WebKit.so.5
#33 0x00007f2c7874f771 in WTF::MainThreadInvoker::event(QEvent*) () from /usr/kde5/lib/libQt5WebKit.so.5
#34 0x00007f2c9b1fe03c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#35 0x00007f2c9b205b02 in QApplication::notify(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#36 0x00007f2c9a566a09 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib64/libQt5Core.so.5
#37 0x00007f2c9a569ec3 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib64/libQt5Core.so.5
#38 0x00007f2c9a5ba213 in ?? () from /usr/lib64/libQt5Core.so.5
#39 0x00007f2c929881ee in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
#40 0x00007f2c92988465 in ?? () from /usr/lib64/libglib-2.0.so.0
#41 0x00007f2c9298852c in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
#42 0x00007f2c9a5b9fbf in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#43 0x00007f2c8dade411 in ?? () from /usr/lib64/libQt5XcbQpa.so.5
#44 0x00007f2c9a5655ba in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#45 0x00007f2c9a56e114 in QCoreApplication::exec() () from /usr/lib64/libQt5Core.so.5
#46 0x00007f2ca1de40f3 in kdemain (argc=<optimized out>, argv=<optimized out>) at /ws/frameworks/applications/konqueror/src/konqmain.cpp:276
#47 0x00007f2c98cd1571 in __libc_start_main () from /lib64/libc.so.6
#48 0x000056078341cbda in _start ()

Since the assert was added in order to force the callers to fix themselves, I'm assuming that the solution is to check for an invalid URL in KIO::rawErrorDetail() and also in KonqFeedIcon::feedFound().
Comment 1 Jonathan Marten 2018-04-30 09:11:13 UTC
Review to fix second case at https://phabricator.kde.org/D12608
Comment 2 Justin Zobel 2020-12-17 05:37:57 UTC
Thank you for the crash report.

As it has been a while since this was reported, can you please test and confirm if this issue is still occurring or if this bug report can be marked as resolved.

I have set the bug status to "needsinfo" pending your response, please change back to "reported" or "resolved/worksforme" when you respond, thank you.
Comment 3 Jonathan Marten 2020-12-17 09:31:06 UTC
The first test case still happens with current Git master.
The second is resolved by the review/commit referenced in comment #2.
Comment 4 Jonathan Marten 2020-12-17 21:30:58 UTC
Git commit a6a9e9e3e3abc8a6a3ffcecaf4a56c0eb837b7df by Jonathan Marten.
Committed on 17/12/2020 at 21:29.
Pushed by marten into branch 'master'.

Akregator feed plugin: Do not assert for a valid but relative URL

For example, "konqueror --part khtml foo".  This passes QUrl("foo"),
a valid but relative URL with no scheme, to KonqFeedIcon::feedFound().
This then asserts when calling KProtocolInfo::protocolClass() for the
blank scheme.

Note that the test case only works with KHTML, and will not reach this
point (an assert will have already happened within KIO) unless the fix
in https://invent.kde.org/frameworks/kio/-/merge_requests/264 is
implemented.

M  +1    -1    plugins/akregator/konqfeedicon.cpp

https://invent.kde.org/network/konqueror/commit/a6a9e9e3e3abc8a6a3ffcecaf4a56c0eb837b7df
Comment 5 Jonathan Marten 2020-12-17 21:32:52 UTC
The previous commit fixes another blank protocol assert for KHTML only.

The main fix for the first test case is requested at
https://invent.kde.org/frameworks/kio/-/merge_requests/264
Comment 6 Jonathan Marten 2020-12-18 12:04:53 UTC
Git commit b4a737f8167e21bf16b1e57ca180d9e4992c91d3 by Jonathan Marten.
Committed on 18/12/2020 at 11:59.
Pushed by marten into branch 'master'.

Do not assert if KIO::rawErrorDetail() is given a URL with no scheme

If the 'reqUrl' points to a URL that is not null but has no scheme,
e.g. QUrl("foo"), then QUrl takes it as as a valid relative URL.
However, the blank scheme is passed to KProtocolInfo::protocolClass()
which asserts.

This can be triggered by, e.g. "konqueror --part webenginepart foo"
where the "foo" generates a relative URL.

Check that the scheme is not empty before calling protocolClass().

M  +6    -1    src/core/job_error.cpp

https://invent.kde.org/frameworks/kio/commit/b4a737f8167e21bf16b1e57ca180d9e4992c91d3
Comment 7 Jonathan Marten 2020-12-26 15:23:36 UTC
All test cases fixed by above commits.