Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Network
Konqueror
Commits
028955b8
Commit
028955b8
authored
Nov 14, 2021
by
Stefano Crocco
Committed by
David Faure
Nov 14, 2021
Browse files
Avoid possible endless loops when opening URLs
parent
fd8ef32e
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/konqmainwindow.cpp
View file @
028955b8
...
...
@@ -660,6 +660,7 @@ void KonqMainWindow::openUrl(KonqView *_view, const QUrl &_url,
//qCDebug(KONQUEROR_LOG) << "trying openView for" << url << "( mimeType" << mimeType << ")";
if
(
hasMimeType
||
KonqUrl
::
isValidNotBlank
(
url
))
{
req
.
args
.
metaData
().
insert
(
"urlRequestedByApp"
,
QString
());
// Built-in view ?
if
(
!
openView
(
mimeType
,
url
,
view
/* can be 0 */
,
req
))
{
//qCDebug(KONQUEROR_LOG) << "openView returned false";
...
...
src/konqrun.cpp
View file @
028955b8
...
...
@@ -45,7 +45,10 @@ 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_inlineErrors
(
!
req
.
args
.
reload
()
||
req
.
userRequestedReload
)
m_pMainWindow
(
mainWindow
),
m_pView
(
_childView
),
m_bFoundMimeType
(
false
),
m_req
(
req
),
m_inlineErrors
(
!
req
.
args
.
reload
()
||
req
.
userRequestedReload
),
m_alreadyProcessedByWebEngine
(
req
.
args
.
metaData
().
contains
(
"AlreadyProcessedByWebEngine"
)),
m_automaticallyAssignedToWebEngine
(
false
)
{
setEnableExternalBrowser
(
false
);
//qCDebug(KONQUEROR_LOG) << "KonqRun::KonqRun() " << this;
...
...
@@ -85,6 +88,9 @@ void KonqRun::foundMimeType(const QString &_type)
// Grab the args back from BrowserRun
m_req
.
args
=
arguments
();
m_req
.
browserArgs
=
browserArguments
();
if
(
!
m_automaticallyAssignedToWebEngine
)
{
m_req
.
args
.
metaData
().
insert
(
"urlRequestedByApp"
,
QString
());
}
bool
tryEmbed
=
true
;
// One case where we shouldn't try to embed, is when the server asks us to save
...
...
@@ -219,12 +225,13 @@ void KonqRun::init()
return
;
}
if
(
url
.
scheme
().
startsWith
(
QLatin1String
(
"http"
))
&&
usingWebEngine
())
{
if
(
url
.
scheme
().
startsWith
(
QLatin1String
(
"http"
))
&&
usingWebEngine
()
&&
!
m_alreadyProcessedByWebEngine
)
{
//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.
m_automaticallyAssignedToWebEngine
=
true
;
mimeTypeDetermined
(
QStringLiteral
(
"text/html"
));
}
else
if
(
url
.
isLocalFile
()
&&
(
url
.
host
().
isEmpty
()
||
(
url
.
host
()
==
QLatin1String
(
"localhost"
))
...
...
@@ -341,7 +348,8 @@ void KonqRun::scanFile()
// To avoid this we assume that the creator of the KonqRun has set m_alreadyProcessedByWebEngine if the URL has
// already been passed to WebEnginePart: it means that it couldn't find a suitable mimetype and we need to do it
// by ourselves, even if it means doing a double GET request.
if
(
m_req
.
args
.
mimeType
().
isEmpty
()
&&
(
url
().
scheme
()
==
"http"
||
url
().
scheme
()
==
"https"
)
&&
usingWebEngine
())
{
if
(
m_req
.
args
.
mimeType
().
isEmpty
()
&&
url
().
scheme
().
startsWith
(
"http"
)
&&
usingWebEngine
()
&&
!
m_alreadyProcessedByWebEngine
)
{
m_automaticallyAssignedToWebEngine
=
true
;
mimeTypeDetermined
(
"text/html"
);
return
;
}
...
...
src/konqrun.h
View file @
028955b8
...
...
@@ -78,7 +78,9 @@ private:
bool
m_bFoundMimeType
;
KonqOpenURLRequest
m_req
;
QUrl
m_mailto
;
bool
m_inlineErrors
;
bool
m_inlineErrors
=
true
;
bool
m_alreadyProcessedByWebEngine
=
false
;
bool
m_automaticallyAssignedToWebEngine
=
false
;
};
#endif // KONQRUN_H
webenginepart/src/webenginepage.cpp
View file @
028955b8
...
...
@@ -39,6 +39,7 @@
#include <KUserTimestamp>
#include <KPasswdServerClient>
#include <KParts/BrowserInterface>
#include <KJobWidgets>
#include <QStandardPaths>
#include <QDesktopWidget>
...
...
@@ -138,8 +139,9 @@ static void checkForDownloadManager(QWidget* widget, QString& cmd)
cmd
=
exeName
;
}
void
WebEnginePage
::
download
(
const
QUrl
&
url
,
const
QString
&
mimetype
,
bool
newWindow
)
void
WebEnginePage
::
download
(
QWebEngineDownloadItem
*
it
,
bool
newWindow
)
{
QUrl
url
=
it
->
url
();
// Integration with a download manager...
if
(
!
url
.
isLocalFile
())
{
QString
managerExe
;
...
...
@@ -155,8 +157,49 @@ void WebEnginePage::download(const QUrl& url, const QString& mimetype, bool newW
KParts
::
BrowserArguments
bArgs
;
bArgs
.
setForcesNewWindow
(
newWindow
);
KParts
::
OpenUrlArguments
urlArgs
;
urlArgs
.
setMimeType
(
mimetype
);
emit
part
()
->
browserExtension
()
->
openUrlRequest
(
url
,
urlArgs
,
bArgs
);
urlArgs
.
setMimeType
(
it
->
mimeType
());
urlArgs
.
metaData
().
insert
(
"AlreadyProcessedByWebEngine"
,
QString
());
if
(
m_urlRequestedByApp
!=
url
)
{
emit
part
()
->
browserExtension
()
->
openUrlRequest
(
url
,
urlArgs
,
bArgs
);
}
else
{
//Don't ask the application to handle the URL, since the application itself asked the part to display it
saveUrlToDisk
(
it
);
}
}
void
WebEnginePage
::
saveUrlToDisk
(
QWebEngineDownloadItem
*
it
)
{
QUrl
url
=
it
->
url
();
QFileDialog
*
dlg
=
new
QFileDialog
(
view
());
dlg
->
setAcceptMode
(
QFileDialog
::
AcceptSave
);
dlg
->
setWindowTitle
(
i18n
(
"Save As"
));
dlg
->
setOption
(
QFileDialog
::
DontConfirmOverwrite
,
false
);
dlg
->
setAttribute
(
Qt
::
WA_DeleteOnClose
);
QString
suggestedName
;
#ifdef WEBENGINEDOWNLOADITEM_USE_PATH
suggestedName
=
it
->
suggestedFileName
();
#endif
if
(
suggestedName
.
isEmpty
())
{
suggestedName
=
it
->
url
().
fileName
();
}
dlg
->
selectFile
(
suggestedName
);
dlg
->
setDirectory
(
QStandardPaths
::
writableLocation
(
QStandardPaths
::
DownloadLocation
));
auto
savePrc
=
[
this
,
dlg
,
url
](){
QUrl
destUrl
=
dlg
->
selectedUrls
().
value
(
0
);
if
(
destUrl
.
isValid
())
{
saveUrlUsingKIO
(
url
,
destUrl
);
}
};
connect
(
dlg
,
&
QDialog
::
accepted
,
dlg
,
savePrc
);
dlg
->
show
();
}
void
WebEnginePage
::
saveUrlUsingKIO
(
const
QUrl
&
origUrl
,
const
QUrl
&
destUrl
)
{
KIO
::
FileCopyJob
*
job
=
KIO
::
file_copy
(
origUrl
,
destUrl
,
-
1
,
KIO
::
Overwrite
);
job
->
addMetaData
(
QStringLiteral
(
"MaxCacheSize"
),
QStringLiteral
(
"0"
));
// Don't store in http cache.
job
->
addMetaData
(
QStringLiteral
(
"cache"
),
QStringLiteral
(
"cache"
));
// Use entry from cache if available.
KJobWidgets
::
setWindow
(
job
,
view
());
job
->
uiDelegate
()
->
setAutoErrorHandlingEnabled
(
true
);
}
void
WebEnginePage
::
requestOpenFileAsTemporary
(
const
QUrl
&
url
,
const
QString
&
mimeType
,
bool
newWindow
)
...
...
@@ -210,17 +253,19 @@ static bool domainSchemeMatch(const QUrl& u1, const QUrl& u2)
bool
WebEnginePage
::
acceptNavigationRequest
(
const
QUrl
&
url
,
NavigationType
type
,
bool
isMainFrame
)
{
if
(
m_urlRequestedByApp
!=
url
)
{
bool
urlRequestedByApp
=
m_urlRequestedByApp
==
url
;
if
(
!
urlRequestedByApp
)
{
m_urlRequestedByApp
=
QUrl
();
}
//Don't open local files using WebEnginePart except if configured to do so by the user. For example
//for example, this ensures that the "Home" link in the introduction page is opened in Dolphin part
//(or whichever part the user has chosen to open directories instead of WebEnginePart
if
(
url
.
isLocalFile
())
{
emit
m_part
->
browserExtension
()
->
openUrlRequest
(
url
);
return
false
;
}
//Don't open local files using WebEnginePart except if configured to do so by the user. For example
//for example, this ensures that the "Home" link in the introduction page is opened in Dolphin part
//(or whichever part the user has chosen to open directories instead of WebEnginePart
if
(
!
urlRequestedByApp
&&
url
.
isLocalFile
())
{
emit
m_part
->
browserExtension
()
->
openUrlRequest
(
url
);
return
false
;
}
// qCDebug(WEBENGINEPART_LOG) << url << "type=" << type;
QUrl
reqUrl
(
url
);
...
...
webenginepart/src/webenginepage.h
View file @
028955b8
...
...
@@ -50,7 +50,7 @@ public:
*/
void
setSslInfo
(
const
WebSslInfo
&
other
);
void
download
(
const
QUrl
&
url
,
const
QString
&
mimetype
,
bool
newWindow
=
false
);
void
download
(
QWebEngineDownloadItem
*
it
,
bool
newWindow
=
false
);
void
requestOpenFileAsTemporary
(
const
QUrl
&
url
,
const
QString
&
mimeType
=
""
,
bool
newWindow
=
false
);
...
...
@@ -144,6 +144,29 @@ private:
*/
void
handleCertificateError
(
WebEnginePartCertificateErrorDlg
*
dlg
);
/**
* @brief Function called when the part is forced to save an URL to disk.
*
* This function should never be needed because the URL should be handled by the application itself.
* However, there can be cases in which this doesn't happen, in particular
* if there's something wrong with the system configuration and the application asks the part to
* handle something it can't display. In this case, it would work as follow:
* - the application asks the part to display the URL
* - the part can't display the URL, so a download is triggered, causing the openUrlRequest signal
* to be emitted
* - the application receives the signal and decides that the part should handle the URL
* - the part can't display the URL and triggers a download
* - endless loop
*
* To avoid this situation, inside download(), the part checks whether it was asked to handle
* the URL by the application. In that case, it doesn't emit the openUrlRequest signal
* but calls this function to directly download the file to disk.
*
* @param it the item describing the download
*/
void
saveUrlToDisk
(
QWebEngineDownloadItem
*
it
);
void
saveUrlUsingKIO
(
const
QUrl
&
origUrl
,
const
QUrl
&
destUrl
);
private:
enum
WebEnginePageSecurity
{
PageUnencrypted
,
PageEncrypted
,
PageMixed
};
...
...
webenginepart/src/webenginepartdownloadmanager.cpp
View file @
028955b8
...
...
@@ -66,7 +66,7 @@ void WebEnginePartDownloadManager::performDownload(QWebEngineDownloadItem* it)
return
;
}
if
(
it
->
url
().
scheme
()
!=
"blob"
)
{
page
->
download
(
it
->
url
(),
it
->
mimeType
()
,
forceNew
);
page
->
download
(
it
,
forceNew
);
}
else
{
downloadBlob
(
it
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment