From 6a46c0c8701fbde143a33e4be61f198e98f53c10 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 19 Sep 2021 12:03:46 +0200 Subject: [PATCH 1/5] Don't open HTTP URLs in another browser than Konqueror, from Konqueror CCBUG: 442636 --- src/konqrun.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/konqrun.cpp b/src/konqrun.cpp index 8bfc22285..1a88e2915 100644 --- a/src/konqrun.cpp +++ b/src/konqrun.cpp @@ -50,6 +50,7 @@ KonqRun::KonqRun(KonqMainWindow *mainWindow, KonqView *_childView, !req.args.reload() || req.userRequestedReload), m_pMainWindow(mainWindow), m_pView(_childView), m_bFoundMimeType(false), m_req(req) { + setEnableExternalBrowser(false); //qCDebug(KONQUEROR_LOG) << "KonqRun::KonqRun() " << this; Q_ASSERT(!m_pMainWindow.isNull()); if (m_pView) { -- 2.33.0 From 8506c585594d9d0cfc0ebe8b869ca05ff7610fa7 Mon Sep 17 00:00:00 2001 From: Stefano Crocco Date: Sun, 19 Sep 2021 20:56:38 +0200 Subject: [PATCH 2/5] Make Konqueror compatible with KIO 5.86.0 Due to a change in KIO::DesktopExecParser::hasSchemeHandler (commit 5fa55a2395cbfb6504e56bf71c869c8e49902e13Q) URLs entered in the navigation bar either were always opened in a new tab or they were opened in another program altogether (for example, man and info URLs). To fix this issue, it has been necessary to copy the implementation of KRun::init and KParts::BrowserRun::init in KonqRun::init, making the necessary changes to restore the old behaviour. BUG: 442636 (cherry picked from commit ba1ea2b74f77832d2a26bb74fed18970eeadf301) --- src/konqrun.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++++--- src/konqrun.h | 11 +++++ 2 files changed, 133 insertions(+), 7 deletions(-) diff --git a/src/konqrun.cpp b/src/konqrun.cpp index 1a88e2915..b45f51767 100644 --- a/src/konqrun.cpp +++ b/src/konqrun.cpp @@ -27,8 +27,17 @@ #include #include #include +#include +#include + #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -48,7 +57,7 @@ KonqRun::KonqRun(KonqMainWindow *mainWindow, KonqView *_childView, // Don't use inline errors on reloading due to auto-refresh sites, but use them in all other cases // (no reload or user-requested reload) !req.args.reload() || req.userRequestedReload), - m_pMainWindow(mainWindow), m_pView(_childView), m_bFoundMimeType(false), m_req(req) + m_pMainWindow(mainWindow), m_pView(_childView), m_bFoundMimeType(false), m_req(req), m_inlineErrors(!req.args.reload() || req.userRequestedReload) { setEnableExternalBrowser(false); //qCDebug(KONQUEROR_LOG) << "KonqRun::KonqRun() " << this; @@ -189,15 +198,121 @@ void KonqRun::handleError(KJob *job) KParts::BrowserRun::handleError(job); } +//Code copied from browserrun.cpp +void KonqRun::switchToErrorUrl(KIO::Error error, QString stringUrl) +{ + KRun::setUrl(makeErrorUrl(error, stringUrl, url())); + setJob(nullptr); + mimeTypeDetermined(QStringLiteral("text/html")); +} + +//Most of the code in this function has been copied copied from krun.cpp and browserrun.cpp void KonqRun::init() { - KParts::BrowserRun::init(); - // Maybe init went to the "let's try stat'ing" part. Then connect to info messages. - // (in case it goes to scanFile, this will be done below) - KIO::StatJob *job = dynamic_cast(KRun::job()); + if (!url().isValid() || url().scheme().isEmpty()) { + if (m_inlineErrors && !url().isValid()) { + switchToErrorUrl(KIO::ERR_MALFORMED_URL, url().toString()); + return; + } + const QString error = !url().isValid() ? url().errorString() : url().toString(); + handleInitError(KIO::ERR_MALFORMED_URL, i18n("Malformed URL\n%1", error)); + qCWarning(KONQUEROR_LOG) << "Malformed URL:" << error; + setError(true); + setFinished(true); + return; + } + + if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("open"), QUrl(), url())) { + QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, url().toDisplayString()); + handleInitError(KIO::ERR_ACCESS_DENIED, msg); + setError(true); + setFinished(true); + return; + } + + if (url().scheme().startsWith(QLatin1String("http")) && usingWebEngine()) { + mimeTypeDetermined(QStringLiteral("text/html")); + } else if (url().isLocalFile() + && (url().host().isEmpty() || (url().host() == QLatin1String("localhost")) + || (url().host().compare(QHostInfo::localHostName(), Qt::CaseInsensitive) == 0))) { + const QString localPath = url().toLocalFile(); + if (!QFile::exists(localPath)) { + if (m_inlineErrors) { + switchToErrorUrl(KIO::ERR_DOES_NOT_EXIST, localPath); + } else { + handleInitError(KIO::ERR_DOES_NOT_EXIST, + i18n("Unable to run the command specified. " + "The file or folder %1 does not exist.", + localPath.toHtmlEscaped())); + setError(true); + setFinished(true); + } + return; + } + + QMimeDatabase db; + QMimeType mime = db.mimeTypeForUrl(url()); + if (mime.isDefault() && !QFileInfo(localPath).isReadable()) { + // Unknown MIME type because the file is unreadable, no point in showing an open-with dialog (#261002) + const QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, localPath); + handleInitError(KIO::ERR_ACCESS_DENIED, msg); + setError(true); + setFinished(true); + return; + } else { + mimeTypeDetermined(mime.name()); + return; + } + } else if (KIO::DesktopExecParser::hasSchemeHandler(url()) && !KProtocolInfo::isKnownProtocol(url())) { + // looks for an application associated with x-scheme-handler/ + KService::Ptr service = KApplicationTrader::preferredService(QLatin1String("x-scheme-handler/") + url().scheme()); + if (service) { + // if there's one... + if (runApplication(*service, QList() << url(), window(), RunFlags{}, QString(), QByteArray())) { + setFinished(true); + return; + } + } else { + // fallback, look for associated helper protocol + Q_ASSERT(KProtocolInfo::isHelperProtocol(url().scheme())); + const auto exec = KProtocolInfo::exec(url().scheme()); + if (exec.isEmpty()) { + // use default MIME type opener for file + mimeTypeDetermined(KProtocolManager::defaultMimetype(url())); + return; + } else { + if (run(exec, QList() << url(), window(), QString(), QString(), QByteArray())) { + setFinished(true); + return; + } + } + } + } + + // Let's see whether it is a directory + + if (!KProtocolManager::supportsListing(url())) { + // No support for listing => it can't be a directory (example: http) + + if (!KProtocolManager::supportsReading(url())) { + // No support for reading files either => we can't do anything (example: mailto URL, with no associated app) + handleInitError(KIO::ERR_UNSUPPORTED_ACTION, i18n("Could not find any application or handler for %1", url().toDisplayString())); + setError(true); + setFinished(true); + return; + } + scanFile(); + return; + } + + // It may be a directory or a file, let's stat + KIO::JobFlags flags = progressInfo() ? KIO::DefaultFlags : KIO::HideProgressInfo; + KIO::StatJob *job = KIO::statDetails(url(), KIO::StatJob::SourceSide, KIO::StatBasic, flags); + KJobWidgets::setWindow(job, window()); + connect(job, &KJob::result, this, &KonqRun::slotStatResult); + setJob(job); if (job && !job->error() && m_pView) { - connect(job, SIGNAL(infoMessage(KJob*,QString,QString)), - m_pView, SLOT(slotInfoMessage(KJob*,QString))); + connect(job, &KIO::StatJob::infoMessage, m_pView, &KonqView::slotInfoMessage); } } diff --git a/src/konqrun.h b/src/konqrun.h index 591b91d19..5be9614b7 100644 --- a/src/konqrun.h +++ b/src/konqrun.h @@ -26,6 +26,8 @@ #include "konqopenurlrequest.h" #include +#include + class KonqMainWindow; class KonqView; @@ -69,6 +71,14 @@ protected: void init() override; void scanFile() override; + /** + * Displays an error page appropriate to the given error code + * + * @param error the error code + * @param stringUrl the string representation of the URL which caused the error + */ + void switchToErrorUrl(KIO::Error error, QString stringUrl); + protected Q_SLOTS: void slotRedirection(KIO::Job *, const QUrl &); @@ -81,6 +91,7 @@ private: bool m_bFoundMimeType; KonqOpenURLRequest m_req; QUrl m_mailto; + bool m_inlineErrors; }; #endif // KONQRUN_H -- 2.33.0 From ec995b8091e97750c12e8e543d298a7a56045d41 Mon Sep 17 00:00:00 2001 From: Stefano Crocco Date: Sun, 19 Sep 2021 22:01:30 +0200 Subject: [PATCH 3/5] Fix signature and avoid calling url() repeatedly (cherry picked from commit 0326d9b8553a7c33d0c1498ca4c0199cc2344e15) --- src/konqrun.cpp | 51 +++++++++++++++++++++++++------------------------ src/konqrun.h | 2 +- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/konqrun.cpp b/src/konqrun.cpp index b45f51767..ccd8d695e 100644 --- a/src/konqrun.cpp +++ b/src/konqrun.cpp @@ -199,22 +199,23 @@ void KonqRun::handleError(KJob *job) } //Code copied from browserrun.cpp -void KonqRun::switchToErrorUrl(KIO::Error error, QString stringUrl) +void KonqRun::switchToErrorUrl(KIO::Error error, const QString &stringUrl) { KRun::setUrl(makeErrorUrl(error, stringUrl, url())); setJob(nullptr); mimeTypeDetermined(QStringLiteral("text/html")); } -//Most of the code in this function has been copied copied from krun.cpp and browserrun.cpp +//Most of the code in this function has been copied from krun.cpp and browserrun.cpp void KonqRun::init() { - if (!url().isValid() || url().scheme().isEmpty()) { - if (m_inlineErrors && !url().isValid()) { - switchToErrorUrl(KIO::ERR_MALFORMED_URL, url().toString()); + QUrl url = KRun::url(); + if (!url.isValid() || url.scheme().isEmpty()) { + if (m_inlineErrors && !url.isValid()) { + switchToErrorUrl(KIO::ERR_MALFORMED_URL, url.toString()); return; } - const QString error = !url().isValid() ? url().errorString() : url().toString(); + const QString error = !url.isValid() ? url.errorString() : url.toString(); handleInitError(KIO::ERR_MALFORMED_URL, i18n("Malformed URL\n%1", error)); qCWarning(KONQUEROR_LOG) << "Malformed URL:" << error; setError(true); @@ -222,20 +223,20 @@ void KonqRun::init() return; } - if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("open"), QUrl(), url())) { - QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, url().toDisplayString()); + if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("open"), QUrl(), url)) { + QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, url.toDisplayString()); handleInitError(KIO::ERR_ACCESS_DENIED, msg); setError(true); setFinished(true); return; } - if (url().scheme().startsWith(QLatin1String("http")) && usingWebEngine()) { + if (url.scheme().startsWith(QLatin1String("http")) && usingWebEngine()) { mimeTypeDetermined(QStringLiteral("text/html")); - } else if (url().isLocalFile() - && (url().host().isEmpty() || (url().host() == QLatin1String("localhost")) - || (url().host().compare(QHostInfo::localHostName(), Qt::CaseInsensitive) == 0))) { - const QString localPath = url().toLocalFile(); + } else if (url.isLocalFile() + && (url.host().isEmpty() || (url.host() == QLatin1String("localhost")) + || (url.host().compare(QHostInfo::localHostName(), Qt::CaseInsensitive) == 0))) { + const QString localPath = url.toLocalFile(); if (!QFile::exists(localPath)) { if (m_inlineErrors) { switchToErrorUrl(KIO::ERR_DOES_NOT_EXIST, localPath); @@ -251,7 +252,7 @@ void KonqRun::init() } QMimeDatabase db; - QMimeType mime = db.mimeTypeForUrl(url()); + QMimeType mime = db.mimeTypeForUrl(url); if (mime.isDefault() && !QFileInfo(localPath).isReadable()) { // Unknown MIME type because the file is unreadable, no point in showing an open-with dialog (#261002) const QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, localPath); @@ -263,25 +264,25 @@ void KonqRun::init() mimeTypeDetermined(mime.name()); return; } - } else if (KIO::DesktopExecParser::hasSchemeHandler(url()) && !KProtocolInfo::isKnownProtocol(url())) { + } else if (KIO::DesktopExecParser::hasSchemeHandler(url) && !KProtocolInfo::isKnownProtocol(url)) { // looks for an application associated with x-scheme-handler/ - KService::Ptr service = KApplicationTrader::preferredService(QLatin1String("x-scheme-handler/") + url().scheme()); + KService::Ptr service = KApplicationTrader::preferredService(QLatin1String("x-scheme-handler/") + url.scheme()); if (service) { // if there's one... - if (runApplication(*service, QList() << url(), window(), RunFlags{}, QString(), QByteArray())) { + if (runApplication(*service, QList() << url, window(), RunFlags{}, QString(), QByteArray())) { setFinished(true); return; } } else { // fallback, look for associated helper protocol - Q_ASSERT(KProtocolInfo::isHelperProtocol(url().scheme())); - const auto exec = KProtocolInfo::exec(url().scheme()); + Q_ASSERT(KProtocolInfo::isHelperProtocol(url.scheme())); + const auto exec = KProtocolInfo::exec(url.scheme()); if (exec.isEmpty()) { // use default MIME type opener for file - mimeTypeDetermined(KProtocolManager::defaultMimetype(url())); + mimeTypeDetermined(KProtocolManager::defaultMimetype(url)); return; } else { - if (run(exec, QList() << url(), window(), QString(), QString(), QByteArray())) { + if (run(exec, QList() << url, window(), QString(), QString(), QByteArray())) { setFinished(true); return; } @@ -291,12 +292,12 @@ void KonqRun::init() // Let's see whether it is a directory - if (!KProtocolManager::supportsListing(url())) { + if (!KProtocolManager::supportsListing(url)) { // No support for listing => it can't be a directory (example: http) - if (!KProtocolManager::supportsReading(url())) { + if (!KProtocolManager::supportsReading(url)) { // No support for reading files either => we can't do anything (example: mailto URL, with no associated app) - handleInitError(KIO::ERR_UNSUPPORTED_ACTION, i18n("Could not find any application or handler for %1", url().toDisplayString())); + handleInitError(KIO::ERR_UNSUPPORTED_ACTION, i18n("Could not find any application or handler for %1", url.toDisplayString())); setError(true); setFinished(true); return; @@ -307,7 +308,7 @@ void KonqRun::init() // It may be a directory or a file, let's stat KIO::JobFlags flags = progressInfo() ? KIO::DefaultFlags : KIO::HideProgressInfo; - KIO::StatJob *job = KIO::statDetails(url(), KIO::StatJob::SourceSide, KIO::StatBasic, flags); + KIO::StatJob *job = KIO::statDetails(url, KIO::StatJob::SourceSide, KIO::StatBasic, flags); KJobWidgets::setWindow(job, window()); connect(job, &KJob::result, this, &KonqRun::slotStatResult); setJob(job); diff --git a/src/konqrun.h b/src/konqrun.h index 5be9614b7..88782ea03 100644 --- a/src/konqrun.h +++ b/src/konqrun.h @@ -77,7 +77,7 @@ protected: * @param error the error code * @param stringUrl the string representation of the URL which caused the error */ - void switchToErrorUrl(KIO::Error error, QString stringUrl); + void switchToErrorUrl(KIO::Error error, const QString &stringUrl); protected Q_SLOTS: void slotRedirection(KIO::Job *, const QUrl &); -- 2.33.0 From d368615b28a97993ce53691731f5152f044f98a2 Mon Sep 17 00:00:00 2001 From: Stefano Crocco Date: Sun, 19 Sep 2021 22:47:03 +0200 Subject: [PATCH 4/5] Add a comment explaining the interaction with WebEnginePart (cherry picked from commit 5c4b0456af2a534c65c60b16add4012566309fb9) --- src/konqrun.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/konqrun.cpp b/src/konqrun.cpp index ccd8d695e..ae9330b43 100644 --- a/src/konqrun.cpp +++ b/src/konqrun.cpp @@ -232,6 +232,11 @@ void KonqRun::init() } if (url.scheme().startsWith(QLatin1String("http")) && usingWebEngine()) { + //This is a fake mimetype, needed only to ensure that the URL will be handled + //by WebEnginePart which will then determine the real mimetype. If it's + //a mimetype it can't handle, it'll emit the KParts::BrowserExtension::openUrlRequest + //passing the real mimetype. Knowing the mimetype, KonqMainWindow::openUrl will handle + //it correctly without needing to use KonqRun again. mimeTypeDetermined(QStringLiteral("text/html")); } else if (url.isLocalFile() && (url.host().isEmpty() || (url.host() == QLatin1String("localhost")) -- 2.33.0 From 036fdfe1666294e5388803eb8877971362347428 Mon Sep 17 00:00:00 2001 From: Andreas Sturmlechner Date: Thu, 30 Sep 2021 13:58:28 +0200 Subject: [PATCH 5/5] Replace handleInitError with KParts::BrowserRun::init Avoids breaking string freeze. Thanks-to: Stefano Crocco Signed-off-by: Andreas Sturmlechner --- src/konqrun.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/konqrun.cpp b/src/konqrun.cpp index ae9330b43..4415c67c4 100644 --- a/src/konqrun.cpp +++ b/src/konqrun.cpp @@ -216,7 +216,7 @@ void KonqRun::init() return; } const QString error = !url.isValid() ? url.errorString() : url.toString(); - handleInitError(KIO::ERR_MALFORMED_URL, i18n("Malformed URL\n%1", error)); + KParts::BrowserRun::init(); qCWarning(KONQUEROR_LOG) << "Malformed URL:" << error; setError(true); setFinished(true); @@ -225,7 +225,7 @@ void KonqRun::init() if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("open"), QUrl(), url)) { QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, url.toDisplayString()); - handleInitError(KIO::ERR_ACCESS_DENIED, msg); + KParts::BrowserRun::init(); setError(true); setFinished(true); return; @@ -246,10 +246,7 @@ void KonqRun::init() if (m_inlineErrors) { switchToErrorUrl(KIO::ERR_DOES_NOT_EXIST, localPath); } else { - handleInitError(KIO::ERR_DOES_NOT_EXIST, - i18n("Unable to run the command specified. " - "The file or folder %1 does not exist.", - localPath.toHtmlEscaped())); + KParts::BrowserRun::init(); setError(true); setFinished(true); } @@ -261,7 +258,7 @@ void KonqRun::init() if (mime.isDefault() && !QFileInfo(localPath).isReadable()) { // Unknown MIME type because the file is unreadable, no point in showing an open-with dialog (#261002) const QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, localPath); - handleInitError(KIO::ERR_ACCESS_DENIED, msg); + KParts::BrowserRun::init(); setError(true); setFinished(true); return; @@ -302,7 +299,7 @@ void KonqRun::init() if (!KProtocolManager::supportsReading(url)) { // No support for reading files either => we can't do anything (example: mailto URL, with no associated app) - handleInitError(KIO::ERR_UNSUPPORTED_ACTION, i18n("Could not find any application or handler for %1", url.toDisplayString())); + KParts::BrowserRun::init(); setError(true); setFinished(true); return; -- 2.33.0