summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-24 16:56:41 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-05-26 07:22:05 +0000
commitcdd438c3aa303e7c46e7e583e4366661323e4385 (patch)
tree40911de2e6b7e73d6e42496fd306b9aacb26ee18
parent384d503d7a12c74762952e802c8cd41a60a88bc1 (diff)
Fix local->remote user navigation
Specifically allow user initiated navigation of the mainframe. Fixes: QTBUG-103778 Change-Id: I4e3d6b4fb606bd0c3cf66e090fba3c97c8c535b4 Reviewed-by: Michal Klocek <michal.klocek@qt.io> (cherry picked from commit 2ba1f04b4589e5883a399b022b7795266c4d4646) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp19
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp65
2 files changed, 81 insertions, 3 deletions
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 0a7256c45..96cd36b3f 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -284,10 +284,23 @@ void InterceptedRequest::Restart()
// Check if non-local access is allowed
if (!allow_remote_ && remote_access_) {
- target_client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_NETWORK_ACCESS_DENIED));
- delete this;
- return;
+ bool granted_special_access = false;
+ switch (ui::PageTransition(request_.transition_type)) {
+ case ui::PAGE_TRANSITION_LINK:
+ case ui::PAGE_TRANSITION_TYPED:
+ if (blink::mojom::ResourceType(request_.resource_type) == blink::mojom::ResourceType::kMainFrame && request_.has_user_gesture)
+ granted_special_access = true; // allow normal explicit navigation
+ break;
+ default:
+ break;
+ }
+ if (!granted_special_access) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_NETWORK_ACCESS_DENIED));
+ delete this;
+ return;
+ }
}
+
// Check if local access is allowed
if (!allow_local_ && local_access_) {
bool granted_special_access = false;
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 3e2f1dd2b..e4924e7d5 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -256,6 +256,8 @@ private Q_SLOTS:
void testChooseFilesParameters();
void fileSystemAccessDialog();
+ void localToRemoteNavigation();
+
private:
static QPoint elementCenter(QWebEnginePage *page, const QString &id);
static bool isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
@@ -327,6 +329,14 @@ void tst_QWebEnginePage::initTestCase()
QWebEngineUrlScheme echo("echo");
echo.setSyntax(QWebEngineUrlScheme::Syntax::Path);
QWebEngineUrlScheme::registerScheme(echo);
+
+ QWebEngineUrlScheme local("local");
+ local.setFlags(QWebEngineUrlScheme::LocalScheme);
+ QWebEngineUrlScheme::registerScheme(local);
+
+ QWebEngineUrlScheme remote("remote");
+ remote.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(remote);
}
void tst_QWebEnginePage::cleanupTestCase()
@@ -4998,6 +5008,61 @@ void tst_QWebEnginePage::isSafeRedirect()
spy.clear();
}
+class LocalRemoteUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ LocalRemoteUrlSchemeHandler(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ }
+ ~LocalRemoteUrlSchemeHandler() = default;
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QBuffer *buffer = new QBuffer(job);
+ buffer->setData("<html><body><a href='remote://test.html' id='link'>Click link</a></body></html>");
+ job->reply("text/html", buffer);
+ loaded = true;
+ }
+ bool loaded = false;
+};
+
+void tst_QWebEnginePage::localToRemoteNavigation()
+{
+ LocalRemoteUrlSchemeHandler local;
+ LocalRemoteUrlSchemeHandler remote;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("local", &local);
+ profile.installUrlSchemeHandler("remote", &remote);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+ view.setPage(&page);
+ page.setUrl(QUrl("local://test.html"));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QVERIFY(local.loaded);
+
+ // Should navigate:
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
+ QVERIFY(remote.loaded);
+ local.loaded = false;
+ remote.loaded = false;
+
+ page.setUrl(QUrl("local://test.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 3, 20000);
+ QVERIFY(local.loaded && !remote.loaded);
+
+ // Should not navigate:
+ page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
+ QTest::qWait(500);
+ QVERIFY(!remote.loaded);
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)