diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-14 16:11:54 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-06-16 16:42:22 +0000 |
commit | 551b83b280bf83137e0c8ceefad59558bfe9e03e (patch) | |
tree | a3133e21416d599db2a635c9bbfec9b560516de7 /tests/auto/widgets/origins | |
parent | 5f4fb14cb0f6b443885e79516f450853e44f650d (diff) |
Stop using Widgets in WebEngineCore tests
With QWebEnginePage in Core we can now make the core tests core-only.
Add the same times moves tests from widgets that only uses core
classes.
Change-Id: I67a25b534912d9a0891e16b0419f0db9bf434e92
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit b8c48ee53009365a39d9dde1f6773048ec5ee4a0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests/auto/widgets/origins')
23 files changed, 0 insertions, 1298 deletions
diff --git a/tests/auto/widgets/origins/CMakeLists.txt b/tests/auto/widgets/origins/CMakeLists.txt deleted file mode 100644 index ca7a6a249..000000000 --- a/tests/auto/widgets/origins/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -include(../../httpserver/httpserver.cmake) -include(../../util/util.cmake) - -qt_internal_add_test(tst_origins - SOURCES - tst_origins.cpp - LIBRARIES - Qt::WebEngineWidgets - Test::HttpServer - Test::Util -) - -set(tst_origins_resource_files - "resources/createObjectURL.html" - "resources/dedicatedWorker.html" - "resources/dedicatedWorker.js" - "resources/mixedSchemes.html" - "resources/mixedSchemesWithCsp.html" - "resources/mixedSchemes_frame.html" - "resources/mixedXHR.html" - "resources/mixedXHR.txt" - "resources/serviceWorker.html" - "resources/serviceWorker.js" - "resources/sharedWorker.html" - "resources/sharedWorker.js" - "resources/subdir/frame2.html" - "resources/subdir/index.html" - "resources/subdir_frame1.html" - "resources/viewSource.html" - "resources/websocket.html" -) - -qt_internal_add_resource(tst_origins "tst_origins" - PREFIX - "/" - FILES - ${tst_origins_resource_files} -) - -qt_internal_extend_target(tst_origins CONDITION QT_FEATURE_webengine_webchannel AND TARGET Qt::WebSockets - DEFINES - WEBSOCKETS - LIBRARIES - Qt::WebSockets -) diff --git a/tests/auto/widgets/origins/origins.pro b/tests/auto/widgets/origins/origins.pro deleted file mode 100644 index 6cf0b2b92..000000000 --- a/tests/auto/widgets/origins/origins.pro +++ /dev/null @@ -1,8 +0,0 @@ -include(../tests.pri) -include(../../shared/http.pri) - -qtConfig(webengine-webchannel):qtHaveModule(websockets) { - QT += websockets - DEFINES += WEBSOCKETS -} - diff --git a/tests/auto/widgets/origins/resources/createObjectURL.html b/tests/auto/widgets/origins/resources/createObjectURL.html deleted file mode 100644 index 133f636bb..000000000 --- a/tests/auto/widgets/origins/resources/createObjectURL.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>createObjectURL</title> - <script> - const blob = new Blob(['foo']); - const result = URL.createObjectURL(blob); - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/dedicatedWorker.html b/tests/auto/widgets/origins/resources/dedicatedWorker.html deleted file mode 100644 index cb4f14e73..000000000 --- a/tests/auto/widgets/origins/resources/dedicatedWorker.html +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>dedicatedWorker</title> - <script> - var done = false; - var result; - var error; - try { - let worker = new Worker("dedicatedWorker.js"); - worker.onmessage = (e) => { done = true; result = e.data; }; - worker.postMessage(41); - } catch (e) { - done = true; error = e.message; - } - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/dedicatedWorker.js b/tests/auto/widgets/origins/resources/dedicatedWorker.js deleted file mode 100644 index 2631939d7..000000000 --- a/tests/auto/widgets/origins/resources/dedicatedWorker.js +++ /dev/null @@ -1 +0,0 @@ -onmessage = (e) => { postMessage(e.data + 1); }; diff --git a/tests/auto/widgets/origins/resources/mixedSchemes.html b/tests/auto/widgets/origins/resources/mixedSchemes.html deleted file mode 100644 index c73e9ecdc..000000000 --- a/tests/auto/widgets/origins/resources/mixedSchemes.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Mixed</title> - <script> - var result; - var canary; - - function setIFrameUrl(url) { - result = undefined; - canary = undefined; - document.getElementById("iframe").setAttribute("src", url); - // Early fire is OK unless the test is expecting cannotLoad. - // If timeout is too short then a false positive is possible. - setTimeout(() => { result = result || "cannotLoad"; }, 500); - } - - addEventListener("load", function() { - document.getElementById("iframe").addEventListener("load", function() { - if (canary && window[0].canary) - result = "canLoadAndAccess"; - else - result = "canLoadButNotAccess"; - }); - }); - </script> - </head> - <body> - <iframe id="iframe"></iframe> - </body> -</html> diff --git a/tests/auto/widgets/origins/resources/mixedSchemesWithCsp.html b/tests/auto/widgets/origins/resources/mixedSchemesWithCsp.html deleted file mode 100644 index ad7cbeeb7..000000000 --- a/tests/auto/widgets/origins/resources/mixedSchemesWithCsp.html +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta http-equiv="Content-Security-Policy" content="frame-src 'none'"> - <title>Mixed</title> - <script> - var result; - var canary; - - function setIFrameUrl(url) { - result = undefined; - canary = undefined; - document.getElementById("iframe").setAttribute("src", url); - // Early fire is OK unless the test is expecting cannotLoad. - // If timeout is too short then a false positive is possible. - setTimeout(() => { result = result || "cannotLoad"; }, 500); - } - - addEventListener("load", function() { - document.getElementById("iframe").addEventListener("load", function() { - if (canary && window[0].canary) - result = "canLoadAndAccess"; - else - result = "canLoadButNotAccess"; - }); - }); - </script> - </head> - <body> - <iframe id="iframe"></iframe> - </body> -</html> diff --git a/tests/auto/widgets/origins/resources/mixedSchemes_frame.html b/tests/auto/widgets/origins/resources/mixedSchemes_frame.html deleted file mode 100644 index 00c20ba37..000000000 --- a/tests/auto/widgets/origins/resources/mixedSchemes_frame.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Mixed - Frame</title> - <script> - var canary = true; - parent.canary = true; - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/mixedXHR.html b/tests/auto/widgets/origins/resources/mixedXHR.html deleted file mode 100644 index 3dfd90006..000000000 --- a/tests/auto/widgets/origins/resources/mixedXHR.html +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Mixed</title> - <script> - var result; - function sendXHR(url) { - result = undefined; - let req = new XMLHttpRequest(); - req.addEventListener("load", () => { result = req.responseText }); - req.addEventListener("error", () => { result = "error"; }); - req.open("GET", url); - req.send(); - } - </script> - </head> - <body> - </body> -</html> diff --git a/tests/auto/widgets/origins/resources/mixedXHR.txt b/tests/auto/widgets/origins/resources/mixedXHR.txt deleted file mode 100644 index b5754e203..000000000 --- a/tests/auto/widgets/origins/resources/mixedXHR.txt +++ /dev/null @@ -1 +0,0 @@ -ok
\ No newline at end of file diff --git a/tests/auto/widgets/origins/resources/redirect.css b/tests/auto/widgets/origins/resources/redirect.css deleted file mode 100644 index 41d7560cc..000000000 --- a/tests/auto/widgets/origins/resources/redirect.css +++ /dev/null @@ -1,8 +0,0 @@ -@font-face { - font-family: 'MyWebFont'; - src: url('redirect1:/resources/Akronim-Regular.woff2') format('woff2'); -} - -body { - font-family: 'MyWebFont', Fallback, sans-serif; -} diff --git a/tests/auto/widgets/origins/resources/redirect.html b/tests/auto/widgets/origins/resources/redirect.html deleted file mode 100644 index 04948e14b..000000000 --- a/tests/auto/widgets/origins/resources/redirect.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>redirect</title> - <link rel="stylesheet" href="redirect1:/resources/redirect.css"> - </head> - <body> - Text - </body> -</html> diff --git a/tests/auto/widgets/origins/resources/serviceWorker.html b/tests/auto/widgets/origins/resources/serviceWorker.html deleted file mode 100644 index 27890c98f..000000000 --- a/tests/auto/widgets/origins/resources/serviceWorker.html +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>serviceWorker</title> - <script> - var done = false; - var error; - try { - navigator.serviceWorker.register("serviceWorker.js") - .then((r) => { done = true; }) - .catch((e) => { done = true; error = e.message; }); - } catch (e) { - done = true; error = e.message; - } - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/serviceWorker.js b/tests/auto/widgets/origins/resources/serviceWorker.js deleted file mode 100644 index 40a8c178f..000000000 --- a/tests/auto/widgets/origins/resources/serviceWorker.js +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/tests/auto/widgets/origins/resources/sharedWorker.html b/tests/auto/widgets/origins/resources/sharedWorker.html deleted file mode 100644 index 8b5a0a794..000000000 --- a/tests/auto/widgets/origins/resources/sharedWorker.html +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>sharedWorker</title> - <script> - var done; - var result; - var error; - try { - let worker = new SharedWorker("sharedWorker.js"); - worker.port.onmessage = (e) => { done = true; result = e.data; }; - worker.port.postMessage(41); - } catch (e) { - done = true; error = e.message; - } - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/sharedWorker.js b/tests/auto/widgets/origins/resources/sharedWorker.js deleted file mode 100644 index 60ef93a5f..000000000 --- a/tests/auto/widgets/origins/resources/sharedWorker.js +++ /dev/null @@ -1,6 +0,0 @@ -onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - port.postMessage(e.data + 1); - }; -}; diff --git a/tests/auto/widgets/origins/resources/subdir/frame2.html b/tests/auto/widgets/origins/resources/subdir/frame2.html deleted file mode 100644 index 3a2f664ca..000000000 --- a/tests/auto/widgets/origins/resources/subdir/frame2.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Subdir - Frame 2</title> - <script> - parent.msg[1] = "world"; - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/subdir/index.html b/tests/auto/widgets/origins/resources/subdir/index.html deleted file mode 100644 index 9c5d5d782..000000000 --- a/tests/auto/widgets/origins/resources/subdir/index.html +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Subdir</title> - - <script> - var msg = []; - </script> - - <!-- for manual testing --> - <script> - window.addEventListener("load", () => { - for (let i of [0, 1]) { - let p = document.createElement("p"); - p.appendChild(document.createTextNode(`frame ${i+1} says: ${msg[i]}`)); - document.body.insertBefore(p, null); - } - }); - </script> - - </head> - <body> - <iframe src="../subdir_frame1.html"></iframe> - <iframe src="frame2.html"></iframe> - </body> -</html> diff --git a/tests/auto/widgets/origins/resources/subdir_frame1.html b/tests/auto/widgets/origins/resources/subdir_frame1.html deleted file mode 100644 index 63973f2f4..000000000 --- a/tests/auto/widgets/origins/resources/subdir_frame1.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Subdir - Frame 1</title> - <script> - parent.msg[0] = "hello"; - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/resources/viewSource.html b/tests/auto/widgets/origins/resources/viewSource.html deleted file mode 100644 index 977074c74..000000000 --- a/tests/auto/widgets/origins/resources/viewSource.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>viewSource</title> - </head> - <body> - <p>viewSource</p> - </body> -</html> diff --git a/tests/auto/widgets/origins/resources/websocket.html b/tests/auto/widgets/origins/resources/websocket.html deleted file mode 100644 index 31db66571..000000000 --- a/tests/auto/widgets/origins/resources/websocket.html +++ /dev/null @@ -1,23 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>WebSocket</title> - <script src="qrc:/qtwebchannel/qwebchannel.js"></script> - <script> - var result; - new QWebChannel(qt.webChannelTransport, channel => { - const ws = new WebSocket(channel.objects.echoServer.url); - ws.addEventListener("open", event => { - ws.send("ok"); - }); - ws.addEventListener("message", event => { - result = event.data; - }); - ws.addEventListener("close", event => { - result = event.code; - }); - }) - </script> - </head> - <body></body> -</html> diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp deleted file mode 100644 index a34404a7e..000000000 --- a/tests/auto/widgets/origins/tst_origins.cpp +++ /dev/null @@ -1,958 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <util.h> -#include "httpserver.h" - -#include <QtCore/qfile.h> -#include <QtTest/QtTest> -#include <QtWebEngineCore/qwebengineurlrequestjob.h> -#include <QtWebEngineCore/qwebengineurlscheme.h> -#include <QtWebEngineCore/qwebengineurlschemehandler.h> -#include <QtWebEngineCore/qwebenginesettings.h> -#include <QtWebEngineCore/qwebengineprofile.h> -#include <QtWebEngineCore/qwebenginepage.h> - -#if defined(WEBSOCKETS) -#include <QtWebSockets/qwebsocket.h> -#include <QtWebSockets/qwebsocketserver.h> -#include <QtWebChannel/qwebchannel.h> -#endif -#include <qaction.h> - -#define QSL QStringLiteral -#define QBAL QByteArrayLiteral - -void registerSchemes() -{ - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax")); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-Secure")); - scheme.setFlags(QWebEngineUrlScheme::SecureScheme); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-Secure-ServiceWorkersAllowed")); - scheme.setFlags(QWebEngineUrlScheme::SecureScheme | QWebEngineUrlScheme::ServiceWorkersAllowed); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-Local")); - scheme.setFlags(QWebEngineUrlScheme::LocalScheme); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-LocalAccessAllowed")); - scheme.setFlags(QWebEngineUrlScheme::LocalAccessAllowed); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-NoAccessAllowed")); - scheme.setFlags(QWebEngineUrlScheme::NoAccessAllowed); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-ServiceWorkersAllowed")); - scheme.setFlags(QWebEngineUrlScheme::ServiceWorkersAllowed); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("PathSyntax-ViewSourceAllowed")); - scheme.setFlags(QWebEngineUrlScheme::ViewSourceAllowed); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("HostSyntax")); - scheme.setSyntax(QWebEngineUrlScheme::Syntax::Host); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("HostSyntax-ContentSecurityPolicyIgnored")); - scheme.setSyntax(QWebEngineUrlScheme::Syntax::Host); - scheme.setFlags(QWebEngineUrlScheme::ContentSecurityPolicyIgnored); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("HostAndPortSyntax")); - scheme.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort); - scheme.setDefaultPort(42); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("HostPortAndUserInformationSyntax")); - scheme.setSyntax(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation); - scheme.setDefaultPort(42); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("redirect1")); - scheme.setFlags(QWebEngineUrlScheme::CorsEnabled); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("redirect2")); - scheme.setFlags(QWebEngineUrlScheme::CorsEnabled); - QWebEngineUrlScheme::registerScheme(scheme); - } - - { - QWebEngineUrlScheme scheme(QBAL("cors")); - scheme.setFlags(QWebEngineUrlScheme::CorsEnabled); - QWebEngineUrlScheme::registerScheme(scheme); - } - -} -Q_CONSTRUCTOR_FUNCTION(registerSchemes) - -class TstUrlSchemeHandler final : public QWebEngineUrlSchemeHandler { - Q_OBJECT - -public: - TstUrlSchemeHandler(QWebEngineProfile *profile) - { - profile->installUrlSchemeHandler(QBAL("tst"), this); - - profile->installUrlSchemeHandler(QBAL("PathSyntax"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-Secure"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-Secure-ServiceWorkersAllowed"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-Local"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-LocalAccessAllowed"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-NoAccessAllowed"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-ServiceWorkersAllowed"), this); - profile->installUrlSchemeHandler(QBAL("PathSyntax-ViewSourceAllowed"), this); - profile->installUrlSchemeHandler(QBAL("HostSyntax"), this); - profile->installUrlSchemeHandler(QBAL("HostSyntax-ContentSecurityPolicyIgnored"), this); - profile->installUrlSchemeHandler(QBAL("HostAndPortSyntax"), this); - profile->installUrlSchemeHandler(QBAL("HostPortAndUserInformationSyntax"), this); - profile->installUrlSchemeHandler(QBAL("redirect1"), this); - profile->installUrlSchemeHandler(QBAL("redirect2"), this); - profile->installUrlSchemeHandler(QBAL("cors"), this); - } - - QList<QUrl> &requests() { return m_requests; } - -private: - void requestStarted(QWebEngineUrlRequestJob *job) override - { - QUrl url = job->requestUrl(); - m_requests << url; - - if (url.scheme() == QBAL("redirect1")) { - url.setScheme(QBAL("redirect2")); - job->redirect(url); - return; - } - - QString pathPrefix = QDir(QT_TESTCASE_SOURCEDIR).canonicalPath(); - QString pathSuffix = url.path(); - QFile *file = new QFile(pathPrefix + pathSuffix, job); - if (!file->open(QIODevice::ReadOnly)) { - job->fail(QWebEngineUrlRequestJob::RequestFailed); - return; - } - QByteArray mimeType = QBAL("text/html"); - if (pathSuffix.endsWith(QSL(".js"))) - mimeType = QBAL("application/javascript"); - else if (pathSuffix.endsWith(QSL(".css"))) - mimeType = QBAL("text/css"); - job->reply(mimeType, file); - } - - QList<QUrl> m_requests; -}; - -class tst_Origins final : public QObject { - Q_OBJECT - -private Q_SLOTS: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); - - void jsUrlCanon(); - void jsUrlRelative(); - void jsUrlOrigin(); - void subdirWithAccess(); - void subdirWithoutAccess(); - void fileAccessRemoteUrl_data(); - void fileAccessRemoteUrl(); - void mixedSchemes(); - void mixedSchemesWithCsp(); - void mixedXHR_data(); - void mixedXHR(); -#if defined(WEBSOCKETS) - void webSocket(); -#endif - void dedicatedWorker(); - void sharedWorker(); - void serviceWorker(); - void viewSource(); - void createObjectURL(); - void redirect(); - -private: - bool verifyLoad(const QUrl &url) - { - QSignalSpy spy(m_page, &QWebEnginePage::loadFinished); - m_page->load(url); - [&spy]() { QTRY_VERIFY_WITH_TIMEOUT(!spy.isEmpty(), 90000); }(); - return !spy.isEmpty() && spy.front().value(0).toBool(); - } - - QVariant eval(const QString &code) - { - return evaluateJavaScriptSync(m_page, code); - } - - QWebEngineProfile m_profile; - QWebEnginePage *m_page = nullptr; - TstUrlSchemeHandler *m_handler = nullptr; -}; - -void tst_Origins::initTestCase() -{ - QTest::ignoreMessage( - QtWarningMsg, - QRegularExpression("Please register the custom scheme 'tst'.*")); - - m_handler = new TstUrlSchemeHandler(&m_profile); -} - -void tst_Origins::cleanupTestCase() -{ - QVERIFY(!m_page); - delete m_handler; -} - -void tst_Origins::init() -{ - m_page = new QWebEnginePage(&m_profile, nullptr); -} - -void tst_Origins::cleanup() -{ - delete m_page; - m_page = nullptr; - m_handler->requests().clear(); -} - -// Test URL parsing and canonicalization in Blink. The implementation of this -// part is mostly shared between Blink and Chromium proper. -void tst_Origins::jsUrlCanon() -{ - QVERIFY(verifyLoad(QSL("about:blank"))); - - // Standard schemes are biased towards the authority part. - QCOMPARE(eval(QSL("new URL(\"http:foo/bar\").href")), QVariant(QSL("http://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"http:/foo/bar\").href")), QVariant(QSL("http://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"http://foo/bar\").href")), QVariant(QSL("http://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"http:///foo/bar\").href")), QVariant(QSL("http://foo/bar"))); - - // The file scheme is however a (particularly) special case. -#ifdef Q_OS_WIN - QCOMPARE(eval(QSL("new URL(\"file:foo/bar\").href")), QVariant(QSL("file://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"file:/foo/bar\").href")), QVariant(QSL("file://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"file://foo/bar\").href")), QVariant(QSL("file://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"file:///foo/bar\").href")), QVariant(QSL("file:///foo/bar"))); -#else - QCOMPARE(eval(QSL("new URL(\"file:foo/bar\").href")), QVariant(QSL("file:///foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"file:/foo/bar\").href")), QVariant(QSL("file:///foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"file://foo/bar\").href")), QVariant(QSL("file://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"file:///foo/bar\").href")), QVariant(QSL("file:///foo/bar"))); -#endif - - // The qrc scheme is a PathSyntax scheme, having only a path and nothing else. - QCOMPARE(eval(QSL("new URL(\"qrc:foo/bar\").href")), QVariant(QSL("qrc:foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"qrc:/foo/bar\").href")), QVariant(QSL("qrc:/foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"qrc://foo/bar\").href")), QVariant(QSL("qrc://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"qrc:///foo/bar\").href")), QVariant(QSL("qrc:///foo/bar"))); - - // Same for unregistered schemes. - QCOMPARE(eval(QSL("new URL(\"tst:foo/bar\").href")), QVariant(QSL("tst:foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"tst:/foo/bar\").href")), QVariant(QSL("tst:/foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"tst://foo/bar\").href")), QVariant(QSL("tst://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"tst:///foo/bar\").href")), QVariant(QSL("tst:///foo/bar"))); - - // A HostSyntax scheme is like http without the port & user information. - QCOMPARE(eval(QSL("new URL(\"HostSyntax:foo/bar\").href")), QVariant(QSL("hostsyntax://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostSyntax:foo:42/bar\").href")), QVariant(QSL("hostsyntax://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostSyntax:a:b@foo/bar\").href")), QVariant(QSL("hostsyntax://foo/bar"))); - - // A HostAndPortSyntax scheme is like http without the user information. - QCOMPARE(eval(QSL("new URL(\"HostAndPortSyntax:foo/bar\").href")), - QVariant(QSL("hostandportsyntax://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostAndPortSyntax:foo:41/bar\").href")), - QVariant(QSL("hostandportsyntax://foo:41/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostAndPortSyntax:foo:42/bar\").href")), - QVariant(QSL("hostandportsyntax://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostAndPortSyntax:a:b@foo/bar\").href")), - QVariant(QSL("hostandportsyntax://foo/bar"))); - - // A HostPortAndUserInformationSyntax scheme is exactly like http. - QCOMPARE(eval(QSL("new URL(\"HostPortAndUserInformationSyntax:foo/bar\").href")), - QVariant(QSL("hostportanduserinformationsyntax://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostPortAndUserInformationSyntax:foo:41/bar\").href")), - QVariant(QSL("hostportanduserinformationsyntax://foo:41/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostPortAndUserInformationSyntax:foo:42/bar\").href")), - QVariant(QSL("hostportanduserinformationsyntax://foo/bar"))); - QCOMPARE(eval(QSL("new URL(\"HostPortAndUserInformationSyntax:a:b@foo/bar\").href")), - QVariant(QSL("hostportanduserinformationsyntax://a:b@foo/bar"))); -} - -// Test relative URL resolution. -void tst_Origins::jsUrlRelative() -{ - QVERIFY(verifyLoad(QSL("about:blank"))); - - // Schemes with hosts, like http, work as expected. - QCOMPARE(eval(QSL("new URL('bar', 'http://foo').href")), QVariant(QSL("http://foo/bar"))); - QCOMPARE(eval(QSL("new URL('baz', 'http://foo/bar').href")), QVariant(QSL("http://foo/baz"))); - QCOMPARE(eval(QSL("new URL('baz', 'http://foo/bar/').href")), QVariant(QSL("http://foo/bar/baz"))); - QCOMPARE(eval(QSL("new URL('/baz', 'http://foo/bar/').href")), QVariant(QSL("http://foo/baz"))); - QCOMPARE(eval(QSL("new URL('./baz', 'http://foo/bar/').href")), QVariant(QSL("http://foo/bar/baz"))); - QCOMPARE(eval(QSL("new URL('../baz', 'http://foo/bar/').href")), QVariant(QSL("http://foo/baz"))); - QCOMPARE(eval(QSL("new URL('../../baz', 'http://foo/bar/').href")), QVariant(QSL("http://foo/baz"))); - QCOMPARE(eval(QSL("new URL('//baz', 'http://foo/bar/').href")), QVariant(QSL("http://baz/"))); - - // In the case of schemes without hosts, relative URLs only work if the URL - // starts with a single slash -- and canonicalization does not guarantee - // this. The following cases all fail with TypeErrors. - QCOMPARE(eval(QSL("new URL('bar', 'tst:foo').href")), QVariant()); - QCOMPARE(eval(QSL("new URL('baz', 'tst:foo/bar').href")), QVariant()); - QCOMPARE(eval(QSL("new URL('bar', 'tst://foo').href")), QVariant()); - QCOMPARE(eval(QSL("new URL('bar', 'tst:///foo').href")), QVariant()); - - // However, registered custom schemes have been patched to allow relative - // URLs even without an initial slash. - QCOMPARE(eval(QSL("new URL('bar', 'qrc:foo').href")), QVariant(QSL("qrc:bar"))); - QCOMPARE(eval(QSL("new URL('baz', 'qrc:foo/bar').href")), QVariant(QSL("qrc:foo/baz"))); - QCOMPARE(eval(QSL("new URL('bar', 'qrc://foo').href")), QVariant()); - QCOMPARE(eval(QSL("new URL('bar', 'qrc:///foo').href")), QVariant()); - - // With a slash it works the same as http except 'foo' is part of the path and not the host. - QCOMPARE(eval(QSL("new URL('bar', 'qrc:/foo').href")), QVariant(QSL("qrc:/bar"))); - QCOMPARE(eval(QSL("new URL('bar', 'qrc:/foo/').href")), QVariant(QSL("qrc:/foo/bar"))); - QCOMPARE(eval(QSL("new URL('baz', 'qrc:/foo/bar').href")), QVariant(QSL("qrc:/foo/baz"))); - QCOMPARE(eval(QSL("new URL('baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc:/foo/bar/baz"))); - QCOMPARE(eval(QSL("new URL('/baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc:/baz"))); - QCOMPARE(eval(QSL("new URL('./baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc:/foo/bar/baz"))); - QCOMPARE(eval(QSL("new URL('../baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc:/foo/baz"))); - QCOMPARE(eval(QSL("new URL('../../baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc:/baz"))); - QCOMPARE(eval(QSL("new URL('../../../baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc:/baz"))); - - // If the relative URL begins with >= 2 slashes, then the scheme is treated - // not as a Syntax::Path scheme but as a Syntax::HostPortAndUserInformation - // scheme. - QCOMPARE(eval(QSL("new URL('//baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc://baz/"))); - QCOMPARE(eval(QSL("new URL('///baz', 'qrc:/foo/bar/').href")), QVariant(QSL("qrc://baz/"))); -} - -// Test origin serialization in Blink, implemented by blink::KURL and -// blink::SecurityOrigin as opposed to GURL and url::Origin. -void tst_Origins::jsUrlOrigin() -{ - QVERIFY(verifyLoad(QSL("about:blank"))); - - // For network protocols the origin string must include the domain and port. - QCOMPARE(eval(QSL("new URL(\"http://foo.com/page.html\").origin")), QVariant(QSL("http://foo.com"))); - QCOMPARE(eval(QSL("new URL(\"https://foo.com/page.html\").origin")), QVariant(QSL("https://foo.com"))); - - // Even though file URL can also have domains, these are not included in the - // origin string by Chromium. The standard does not specify a value here, - // but suggests 'null' (https://url.spec.whatwg.org/#origin). - QCOMPARE(eval(QSL("new URL(\"file:/etc/passwd\").origin")), QVariant(QSL("file://"))); - QCOMPARE(eval(QSL("new URL(\"file://foo.com/etc/passwd\").origin")), QVariant(QSL("file://"))); - - // Unregistered schemes behave like file. - QCOMPARE(eval(QSL("new URL(\"tst:/banana\").origin")), QVariant(QSL("tst://"))); - QCOMPARE(eval(QSL("new URL(\"tst://foo.com/banana\").origin")), QVariant(QSL("tst://"))); - - // The non-PathSyntax schemes should have hosts and potentially ports. - QCOMPARE(eval(QSL("new URL(\"HostSyntax:foo:41/bar\").origin")), - QVariant(QSL("hostsyntax://foo"))); - QCOMPARE(eval(QSL("new URL(\"HostAndPortSyntax:foo:41/bar\").origin")), - QVariant(QSL("hostandportsyntax://foo:41"))); - QCOMPARE(eval(QSL("new URL(\"HostAndPortSyntax:foo:42/bar\").origin")), - QVariant(QSL("hostandportsyntax://foo"))); - QCOMPARE(eval(QSL("new URL(\"HostPortAndUserInformationSyntax:foo:41/bar\").origin")), - QVariant(QSL("hostportanduserinformationsyntax://foo:41"))); - QCOMPARE(eval(QSL("new URL(\"HostPortAndUserInformationSyntax:foo:42/bar\").origin")), - QVariant(QSL("hostportanduserinformationsyntax://foo"))); - - // A PathSyntax scheme should have a 'universal' origin. - QCOMPARE(eval(QSL("new URL(\"PathSyntax:foo\").origin")), QVariant(QSL("pathsyntax:"))); - QCOMPARE(eval(QSL("new URL(\"qrc:/crysis.css\").origin")), QVariant(QSL("qrc:"))); - QCOMPARE(eval(QSL("new URL(\"qrc://foo.com/crysis.css\").origin")), QVariant(QSL("qrc:"))); - - // The NoAccessAllowed flag forces opaque origins. - QCOMPARE(eval(QSL("new URL(\"PathSyntax-NoAccessAllowed:foo\").origin")), - QVariant(QSL("null"))); -} - -class ScopedAttribute { -public: - ScopedAttribute(QWebEngineSettings *settings, QWebEngineSettings::WebAttribute attribute, bool newValue) - : m_settings(settings) - , m_attribute(attribute) - , m_oldValue(m_settings->testAttribute(m_attribute)) - { - m_settings->setAttribute(m_attribute, newValue); - } - ~ScopedAttribute() - { - m_settings->setAttribute(m_attribute, m_oldValue); - } -private: - QWebEngineSettings *m_settings; - QWebEngineSettings::WebAttribute m_attribute; - bool m_oldValue; -}; - -// Test same-origin policy of file, qrc and custom schemes. -// -// Note the test case involves the main page trying to load an iframe from a -// file that resides in a parent directory. This is just a small detail to -// demonstrate the difference with Firefox where such access is not allowed. -void tst_Origins::subdirWithAccess() -{ - ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, true); - - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/subdir/index.html")); - QCOMPARE(eval(QSL("msg[0]")), QVariant(QSL("hello"))); - QCOMPARE(eval(QSL("msg[1]")), QVariant(QSL("world"))); - - QVERIFY(verifyLoad(QSL("qrc:/resources/subdir/index.html"))); - QCOMPARE(eval(QSL("msg[0]")), QVariant(QSL("hello"))); - QCOMPARE(eval(QSL("msg[1]")), QVariant(QSL("world"))); - - QVERIFY(verifyLoad(QSL("tst:/resources/subdir/index.html"))); - QCOMPARE(eval(QSL("msg[0]")), QVariant(QSL("hello"))); - QCOMPARE(eval(QSL("msg[1]")), QVariant(QSL("world"))); -} - -// In this variation the LocalContentCanAccessFileUrls attribute is disabled. As -// a result all file URLs will be considered to have unique/opaque origins, that -// is, they are not the 'same origin as' any other origin. -// -// Note that this applies only to file URLs and not qrc or custom schemes. -// -// See also (in Blink): -// - the allow_file_access_from_file_urls option and -// - the blink::SecurityOrigin::BlockLocalAccessFromLocalOrigin() method. -void tst_Origins::subdirWithoutAccess() -{ - ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, false); - - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/subdir/index.html")); - QCOMPARE(eval(QSL("msg[0]")), QVariant()); - QCOMPARE(eval(QSL("msg[1]")), QVariant()); - - QVERIFY(verifyLoad(QSL("qrc:/resources/subdir/index.html"))); - QCOMPARE(eval(QSL("msg[0]")), QVariant(QSL("hello"))); - QCOMPARE(eval(QSL("msg[1]")), QVariant(QSL("world"))); - - QVERIFY(verifyLoad(QSL("tst:/resources/subdir/index.html"))); - QCOMPARE(eval(QSL("msg[0]")), QVariant(QSL("hello"))); - QCOMPARE(eval(QSL("msg[1]")), QVariant(QSL("world"))); -} - -void tst_Origins::fileAccessRemoteUrl_data() -{ - QTest::addColumn<bool>("EnableAccess"); - QTest::addRow("enabled") << true; - QTest::addRow("disabled") << false; -} - -void tst_Origins::fileAccessRemoteUrl() -{ - QFETCH(bool, EnableAccess); - - HttpServer server; - server.setResourceDirs({ QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() + "/resources" }); - QVERIFY(server.start()); - - ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessRemoteUrls, EnableAccess); - if (!EnableAccess) - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("blocked by CORS policy"))); - - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.html")); - - eval("sendXHR('" + server.url("/mixedXHR.txt").toString() + "')"); - QTRY_COMPARE(eval("result"), (EnableAccess ? QString("ok") : QString("error"))); -} - -// Load the main page over one scheme with an iframe over another scheme. -// -// For file and qrc schemes, the iframe should load but it should not be -// possible for scripts in different frames to interact. -// -// Additionally for unregistered custom schemes and custom schemes without -// LocalAccessAllowed it should not be possible to load an iframe over the -// file: scheme. -void tst_Origins::mixedSchemes() -{ - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedSchemes.html")); - eval("setIFrameUrl('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedSchemes_frame.html')"); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - - QVERIFY(verifyLoad(QSL("qrc:/resources/mixedSchemes.html"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval("setIFrameUrl('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedSchemes_frame.html')"); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - - QVERIFY(verifyLoad(QSL("tst:/resources/mixedSchemes.html"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource"))); - eval("setIFrameUrl('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedSchemes_frame.html')"); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - - QVERIFY(verifyLoad(QSL("PathSyntax:/resources/mixedSchemes.html"))); - eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource"))); - eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad"))); - eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')")); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - - QVERIFY(verifyLoad(QSL("PathSyntax-LocalAccessAllowed:/resources/mixedSchemes.html"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - - QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/mixedSchemes.html"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource"))); - eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - - QVERIFY(verifyLoad(QSL("HostSyntax://a/resources/mixedSchemes.html"))); - eval(QSL("setIFrameUrl('HostSyntax://a/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('HostSyntax://b/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); -} - -// Like mixedSchemes but adds a Content-Security-Policy: frame-src 'none' header. -void tst_Origins::mixedSchemesWithCsp() -{ - QVERIFY(verifyLoad(QSL("HostSyntax://a/resources/mixedSchemesWithCsp.html"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("violates the following Content Security Policy"))); - eval(QSL("setIFrameUrl('HostSyntax://a/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("violates the following Content Security Policy"))); - eval(QSL("setIFrameUrl('HostSyntax://b/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); - - QVERIFY(verifyLoad(QSL("HostSyntax-ContentSecurityPolicyIgnored://a/resources/mixedSchemesWithCsp.html"))); - eval(QSL("setIFrameUrl('HostSyntax-ContentSecurityPolicyIgnored://a/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess"))); - QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError"))); - eval(QSL("setIFrameUrl('HostSyntax-ContentSecurityPolicyIgnored://b/resources/mixedSchemes_frame.html')")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess"))); -} - -// Load the main page over one scheme, then make an XMLHttpRequest to a -// different scheme. -// -// Cross-origin XMLHttpRequests can only be made to CORS-enabled schemes. These -// include the builtin schemes http, https, data, and chrome, as well as custom -// schemes with the CorsEnabled flag. -void tst_Origins::mixedXHR_data() -{ - QTest::addColumn<QString>("url"); - QTest::addColumn<QString>("command"); - QTest::addColumn<QVariant>("result"); - QTest::newRow("file->file") << QString("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.html") - << QString("sendXHR('file:" - + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - QTest::newRow("file->qrc") << QString("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.html") - << QString("sendXHR('qrc:/resources/mixedXHR.txt')") - << QVariant(QString("error")); - QTest::newRow("file->tst") << QString("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.html") - << QString("sendXHR('tst:/resources/mixedXHR.txt')") - << QVariant(QString("error")); - QTest::newRow("file->data") << QString("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.html") - << QString("sendXHR('data:,ok')") << QVariant(QString("ok")); - QTest::newRow("file->cors") << QString("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.html") - << QString("sendXHR('cors:/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - - QTest::newRow("qrc->file") << QString("qrc:/resources/mixedXHR.html") - << QString("sendXHR('file:" - + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - QTest::newRow("qrc->qrc") << QString("qrc:/resources/mixedXHR.html") - << QString("sendXHR('qrc:/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - QTest::newRow("qrc->tst") << QString("qrc:/resources/mixedXHR.html") - << QString("sendXHR('tst:/resources/mixedXHR.txt')") - << QVariant(QString("error")); - QTest::newRow("qrc->data") << QString("qrc:/resources/mixedXHR.html") - << QString("sendXHR('data:,ok')") - << QVariant(QString("ok")); - QTest::newRow("qrc->cors") << QString("qrc:/resources/mixedXHR.html") - << QString("sendXHR('cors:/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - - QTest::newRow("tst->file") << QString("tst:/resources/mixedXHR.html") - << QString("sendXHR('file:" - + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/mixedXHR.txt')") - << QVariant(QString("error")); - QTest::newRow("tst->qrc") << QString("tst:/resources/mixedXHR.html") - << QString("sendXHR('qrc:/resources/mixedXHR.txt')") - << QVariant(QString("error")); - QTest::newRow("tst->tst") << QString("tst:/resources/mixedXHR.html") - << QString("sendXHR('tst:/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - QTest::newRow("tst->data") << QString("tst:/resources/mixedXHR.html") - << QString("sendXHR('data:,ok')") - << QVariant(QString("ok")); - QTest::newRow("tst->cors") << QString("tst:/resources/mixedXHR.html") - << QString("sendXHR('cors:/resources/mixedXHR.txt')") - << QVariant(QString("ok")); - -} - - -void tst_Origins::mixedXHR() -{ - QFETCH(QString, url); - QFETCH(QString, command); - QFETCH(QVariant, result); - - QVERIFY(verifyLoad(url)); - eval(command); - QTRY_COMPARE(eval(QString("result")), result); -} - -#if defined(WEBSOCKETS) -class EchoServer : public QObject { - Q_OBJECT - Q_PROPERTY(QUrl url READ url NOTIFY urlChanged) -public: - EchoServer() : webSocketServer(QSL("EchoServer"), QWebSocketServer::NonSecureMode) - { - connect(&webSocketServer, &QWebSocketServer::newConnection, this, &EchoServer::onNewConnection); - } - - bool listen() - { - if (webSocketServer.listen(QHostAddress::Any)) { - Q_EMIT urlChanged(); - return true; - } - return false; - } - - QUrl url() const - { - return webSocketServer.serverUrl(); - } - -Q_SIGNALS: - void urlChanged(); - -private: - void onNewConnection() - { - QWebSocket *socket = webSocketServer.nextPendingConnection(); - connect(socket, &QWebSocket::textMessageReceived, this, &EchoServer::onTextMessageReceived); - connect(socket, &QWebSocket::disconnected, socket, &QObject::deleteLater); - } - - void onTextMessageReceived(const QString &message) - { - QWebSocket *socket = qobject_cast<QWebSocket *>(sender()); - socket->sendTextMessage(message); - } - - QWebSocketServer webSocketServer; -}; - -// Try opening a WebSocket from pages loaded over various URL schemes. -void tst_Origins::webSocket() -{ - EchoServer echoServer; - QWebChannel channel; - channel.registerObject(QSL("echoServer"), &echoServer); - m_page->setWebChannel(&channel); - QVERIFY(echoServer.listen()); - - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/websocket.html")); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok"))); - - QVERIFY(verifyLoad(QSL("qrc:/resources/websocket.html"))); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok"))); - - // Unregistered schemes can also open WebSockets (since Chromium 71) - QVERIFY(verifyLoad(QSL("tst:/resources/websocket.html"))); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok"))); - - // Even an insecure registered scheme can open WebSockets. - QVERIFY(verifyLoad(QSL("PathSyntax:/resources/websocket.html"))); - QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok"))); -} -#endif -// Create a (Dedicated)Worker. Since dedicated workers can only be accessed from -// one page, there is not much need for security restrictions. -void tst_Origins::dedicatedWorker() -{ - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/dedicatedWorker.html")); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QCOMPARE(eval(QSL("result")), QVariant(42)); - - QVERIFY(verifyLoad(QSL("qrc:/resources/dedicatedWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QCOMPARE(eval(QSL("result")), QVariant(42)); - - // Unregistered schemes can also create Workers (since Chromium 71) - QVERIFY(verifyLoad(QSL("tst:/resources/dedicatedWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QCOMPARE(eval(QSL("result")), QVariant(42)); - - // Even an insecure registered scheme can create Workers. - QVERIFY(verifyLoad(QSL("PathSyntax:/resources/dedicatedWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QCOMPARE(eval(QSL("result")), QVariant(42)); - - // But not if the NoAccessAllowed flag is set. - QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/dedicatedWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("cannot be accessed from origin 'null'"))); -} - -// Create a SharedWorker. Shared workers can be accessed from multiple pages, -// and therefore the same-origin policy applies. -void tst_Origins::sharedWorker() -{ - { - ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, false); - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/sharedWorker.html")); - QTRY_VERIFY_WITH_TIMEOUT(eval(QSL("done")).toBool(), 10000); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("cannot be accessed from origin 'null'"))); - } - - { - ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, true); - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/sharedWorker.html")); - QTRY_VERIFY_WITH_TIMEOUT(eval(QSL("done")).toBool(), 10000); - QCOMPARE(eval(QSL("result")), QVariant(42)); - } - - QVERIFY(verifyLoad(QSL("qrc:/resources/sharedWorker.html"))); - QTRY_VERIFY_WITH_TIMEOUT(eval(QSL("done")).toBool(), 10000); - QCOMPARE(eval(QSL("result")), QVariant(42)); - - // Unregistered schemes should not create SharedWorkers. - - QVERIFY(verifyLoad(QSL("PathSyntax:/resources/sharedWorker.html"))); - QTRY_VERIFY_WITH_TIMEOUT(eval(QSL("done")).toBool(), 10000); - QCOMPARE(eval(QSL("result")), QVariant(42)); - - QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/sharedWorker.html"))); - QTRY_VERIFY_WITH_TIMEOUT(eval(QSL("done")).toBool(), 10000); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("denied to origin 'null'"))); -} - -// Service workers have to be explicitly enabled for a scheme. -void tst_Origins::serviceWorker() -{ - QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/serviceWorker.html")); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("The URL protocol of the current origin ('file://') is not supported."))); - - QVERIFY(verifyLoad(QSL("qrc:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("The URL protocol of the current origin ('qrc:') is not supported."))); - - QVERIFY(verifyLoad(QSL("tst:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("Cannot read property 'register' of undefined"))); - - QVERIFY(verifyLoad(QSL("PathSyntax:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("Cannot read property 'register' of undefined"))); - - QVERIFY(verifyLoad(QSL("PathSyntax-Secure:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("The URL protocol of the current origin ('pathsyntax-secure:') is not supported."))); - - QVERIFY(verifyLoad(QSL("PathSyntax-ServiceWorkersAllowed:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("Cannot read property 'register' of undefined"))); - - QVERIFY(verifyLoad(QSL("PathSyntax-Secure-ServiceWorkersAllowed:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QCOMPARE(eval(QSL("error")), QVariant()); - - QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/serviceWorker.html"))); - QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("Cannot read property 'register' of undefined"))); -} - -// Support for view-source must be enabled explicitly. -void tst_Origins::viewSource() -{ - QVERIFY(verifyLoad("view-source:file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/viewSource.html")); -#ifdef Q_OS_WIN - QCOMPARE(m_page->requestedUrl().toString(), - "file:///" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/viewSource.html"); -#else - QCOMPARE(m_page->requestedUrl().toString(), - "file://" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() - + "/resources/viewSource.html"); -#endif - - QVERIFY(verifyLoad(QSL("view-source:qrc:/resources/viewSource.html"))); - QCOMPARE(m_page->requestedUrl().toString(), QSL("qrc:/resources/viewSource.html")); - - QVERIFY(verifyLoad(QSL("view-source:tst:/resources/viewSource.html"))); - QCOMPARE(m_page->requestedUrl().toString(), QSL("about:blank")); - - QVERIFY(verifyLoad(QSL("view-source:PathSyntax:/resources/viewSource.html"))); - QCOMPARE(m_page->requestedUrl().toString(), QSL("about:blank")); - - QVERIFY(verifyLoad(QSL("view-source:PathSyntax-ViewSourceAllowed:/resources/viewSource.html"))); - QCOMPARE(m_page->requestedUrl().toString(), QSL("pathsyntax-viewsourceallowed:/resources/viewSource.html")); -} - -void tst_Origins::createObjectURL() -{ - // Legal for registered custom schemes. - QVERIFY(verifyLoad(QSL("qrc:/resources/createObjectURL.html"))); - QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:qrc:"))); - - // Also legal for unregistered schemes (since Chromium 71) - QVERIFY(verifyLoad(QSL("tst:/resources/createObjectURL.html"))); - QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:"))); -} - -void tst_Origins::redirect() -{ - QVERIFY(verifyLoad(QSL("redirect1:/resources/redirect.html"))); - QTRY_COMPARE(m_handler->requests().size(), 7); - QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect1:/resources/redirect.html"))); - QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("redirect2:/resources/redirect.html"))); - QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect1:/resources/redirect.css"))); - QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("redirect2:/resources/redirect.css"))); - QCOMPARE(m_handler->requests()[4], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2"))); - QCOMPARE(m_handler->requests()[5], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2"))); - QCOMPARE(m_handler->requests()[6], QUrl(QStringLiteral("redirect2:/resources/Akronim-Regular.woff2"))); -} - -QTEST_MAIN(tst_Origins) -#include "tst_origins.moc" diff --git a/tests/auto/widgets/origins/tst_origins.qrc b/tests/auto/widgets/origins/tst_origins.qrc deleted file mode 100644 index fcf54aaea..000000000 --- a/tests/auto/widgets/origins/tst_origins.qrc +++ /dev/null @@ -1,22 +0,0 @@ -<!DOCTYPE RCC> -<RCC version="1.0"> -<qresource> - <file>resources/createObjectURL.html</file> - <file>resources/dedicatedWorker.html</file> - <file>resources/dedicatedWorker.js</file> - <file>resources/mixedSchemes.html</file> - <file>resources/mixedSchemesWithCsp.html</file> - <file>resources/mixedSchemes_frame.html</file> - <file>resources/mixedXHR.html</file> - <file>resources/mixedXHR.txt</file> - <file>resources/serviceWorker.html</file> - <file>resources/serviceWorker.js</file> - <file>resources/sharedWorker.html</file> - <file>resources/sharedWorker.js</file> - <file>resources/subdir/frame2.html</file> - <file>resources/subdir/index.html</file> - <file>resources/subdir_frame1.html</file> - <file>resources/viewSource.html</file> - <file>resources/websocket.html</file> -</qresource> -</RCC> |