Commit 00314e59 authored by Stefano Crocco's avatar Stefano Crocco Committed by David Faure
Browse files

Fix a bug causing an endless loop with WebEnginePart

To avoid to pass the URL back to WebEnginePart, don't rely on the fact
that WebEnginePart is the first part in the list.

It can happen that WebEnginePart thinks it can't handle an URL even if,
basing on its mimetype, it should. In this case, in
UrlLoader::decideEmbedOrSave, m_view->supportsMimeType will return true,
so m_service will be a WebEnginePart, even if it's not the first in the list of
preferred parts for that mimetype. However, the code which explicitly
avoids using WebEnginePart when asked not to assumed that WebEnginePart
was the preferred mimetype, using services[1] to find the service to
use.

This can have two outcomes: if WebEnginePart is neither the first nor
the second preferred service, the effect would be to use a less
preferred service instead of the preferred one. However, if the
WebEnginePart was the second preferred service, this bug leads to an
endless loop because, m_service is set to services[1] which is
WebEnginePart: exactly what was to be avoided.

This can be seen, for example, by attempting to download this image from
Wikipedia:
https://en.wikipedia.org/wiki/Black_body#/media/File:Black_body_realization.svg
If the preferred part for image/svg+xml is SvgPart and the second is
WebEnginePart, pressing the "Download this file" button, then "Download
original file" leads to an endless loop.
parent a7c3e78d
Pipeline #165130 passed with stage
in 4 minutes and 55 seconds
......@@ -161,9 +161,11 @@ void UrlLoader::goOn()
bool UrlLoader::decideEmbedOrSave()
{
const QLatin1String webEngineName("webenginepart");
//Use WebEnginePart for konq: URLs even if it's not the default html engine
if (KonqUrl::hasKonqScheme(m_url)) {
m_service = KService::serviceByDesktopName("webenginepart");
m_service = KService::serviceByDesktopName(webEngineName);
} else {
//Check whether the view can display the mimetype, but only if the URL hasn't been explicitly
//typed by the user: in this case, use the preferred service. This is needed to avoid the situation
......@@ -183,10 +185,12 @@ bool UrlLoader::decideEmbedOrSave()
* is true, use the second preferred service (if any); otherwise return false. This will offer the user
* the option to open or save, instead.
*/
if (m_dontPassToWebEnginePart && m_service->desktopEntryName() == QLatin1String("webenginepart")) {
if (m_dontPassToWebEnginePart && m_service->desktopEntryName() == webEngineName) {
KService::List services = KMimeTypeTrader::self()->query(m_mimeType, QStringLiteral("KParts/ReadOnlyPart"));
if (services.length() >= 2) {
m_service = services.at(1);
auto findService = [webEngineName](KService::Ptr s){return s->desktopEntryName() != webEngineName;};
QList<KService::Ptr>::const_iterator serviceToUse = std::find_if(services.constBegin(), services.constEnd(), findService);
if (serviceToUse != services.constEnd()) {
m_service = *serviceToUse;
} else {
m_service = nullptr;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment