1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-21 03:06:34 +01:00

WebPage: Register QWebChannel on isolated ApplicationWorld

This way scripts on pages don't have access to it.
Exception is qupzilla: scheme as internal pages requires the bridge.

GreaseMonkey userscripts now runs on ApplicationWorld too. This fixes
userscript that depend on script world being isolated from main page world.
Tested with 4ChanX + OneeChan.
This commit is contained in:
David Rosca 2018-01-10 12:36:41 +01:00
parent b291c27d4e
commit 4bf85ee3cb
9 changed files with 57 additions and 22 deletions

View File

@ -273,11 +273,19 @@ MainApplication::MainApplication(int &argc, char** argv)
QWebEngineScript script; QWebEngineScript script;
script.setName(QSL("_falkon_webchannel")); script.setName(QSL("_falkon_webchannel"));
script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setInjectionPoint(QWebEngineScript::DocumentCreation);
script.setWorldId(QWebEngineScript::MainWorld); script.setWorldId(WebPage::SafeJsWorld);
script.setRunsOnSubFrames(true); script.setRunsOnSubFrames(true);
script.setSourceCode(Scripts::setupWebChannel()); script.setSourceCode(Scripts::setupWebChannel(script.worldId()));
m_webProfile->scripts()->insert(script); m_webProfile->scripts()->insert(script);
QWebEngineScript script2;
script2.setName(QSL("_qupzilla_webchannel2"));
script2.setInjectionPoint(QWebEngineScript::DocumentCreation);
script2.setWorldId(WebPage::UnsafeJsWorld);
script2.setRunsOnSubFrames(true);
script2.setSourceCode(Scripts::setupWebChannel(script2.worldId()));
m_webProfile->scripts()->insert(script2);
if (!isPrivate()) { if (!isPrivate()) {
m_sessionManager = new SessionManager(this); m_sessionManager = new SessionManager(this);
m_autoSaver = new AutoSaver(this); m_autoSaver = new AutoSaver(this);

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* Falkon - Qt web browser * Falkon - Qt web browser
* Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@
#include "passwordmanager.h" #include "passwordmanager.h"
#include "qztools.h" #include "qztools.h"
#include "scripts.h" #include "scripts.h"
#include "webpage.h"
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QXmlStreamReader> #include <QXmlStreamReader>
@ -45,7 +46,7 @@ AutoFill::AutoFill(QObject* parent)
QWebEngineScript script; QWebEngineScript script;
script.setName(QSL("_falkon_autofill")); script.setName(QSL("_falkon_autofill"));
script.setInjectionPoint(QWebEngineScript::DocumentReady); script.setInjectionPoint(QWebEngineScript::DocumentReady);
script.setWorldId(QWebEngineScript::MainWorld); script.setWorldId(WebPage::SafeJsWorld);
script.setRunsOnSubFrames(true); script.setRunsOnSubFrames(true);
script.setSourceCode(Scripts::setupFormObserver()); script.setSourceCode(Scripts::setupFormObserver());
mApp->webProfile()->scripts()->insert(script); mApp->webProfile()->scripts()->insert(script);

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* Falkon - Qt web browser * Falkon - Qt web browser
* Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -18,13 +18,17 @@
#include "scripts.h" #include "scripts.h"
#include "qztools.h" #include "qztools.h"
#include "webpage.h"
#include <QUrlQuery> #include <QUrlQuery>
QString Scripts::setupWebChannel() QString Scripts::setupWebChannel(quint32 worldId)
{ {
QString source = QL1S("(function() {" QString source = QL1S("// ==UserScript==\n"
"%1" "// %1\n"
"// ==/UserScript==\n\n"
"(function() {"
"%2"
"" ""
"function registerExternal(e) {" "function registerExternal(e) {"
" window.external = e;" " window.external = e;"
@ -66,7 +70,13 @@ QString Scripts::setupWebChannel()
"" ""
"})()"); "})()");
return source.arg(QzTools::readAllFileContents(QSL(":/qtwebchannel/qwebchannel.js"))); QString match;
if (worldId == WebPage::SafeJsWorld) {
match = QSL("@exclude qupzilla:*");
} else {
match = QSL("@include qupzilla:*");
}
return source.arg(match, QzTools::readAllFileContents(QSL(":/qtwebchannel/qwebchannel.js")));
} }
QString Scripts::setupFormObserver() QString Scripts::setupFormObserver()

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* Falkon - Qt web browser * Falkon - Qt web browser
* Copyright (C) 2015-2016 David Rosca <nowrep@gmail.com> * Copyright (C) 2015-2018 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -28,7 +28,7 @@ class QWebEngineView;
class FALKON_EXPORT Scripts class FALKON_EXPORT Scripts
{ {
public: public:
static QString setupWebChannel(); static QString setupWebChannel(quint32 worldId);
static QString setupFormObserver(); static QString setupFormObserver();
static QString setCss(const QString &css); static QString setCss(const QString &css);

View File

@ -71,9 +71,7 @@ WebPage::WebPage(QObject* parent)
, m_blockAlerts(false) , m_blockAlerts(false)
, m_secureStatus(false) , m_secureStatus(false)
{ {
QWebChannel *channel = new QWebChannel(this); setupWebChannelForUrl(QUrl());
ExternalJsObject::setupWebChannel(channel, this);
setWebChannel(channel);
connect(this, &QWebEnginePage::loadProgress, this, &WebPage::progress); connect(this, &QWebEnginePage::loadProgress, this, &WebPage::progress);
connect(this, &QWebEnginePage::loadFinished, this, &WebPage::finished); connect(this, &QWebEnginePage::loadFinished, this, &WebPage::finished);
@ -167,13 +165,13 @@ WebHitTestResult WebPage::hitTestContent(const QPoint &pos) const
void WebPage::scroll(int x, int y) void WebPage::scroll(int x, int y)
{ {
runJavaScript(QSL("window.scrollTo(window.scrollX + %1, window.scrollY + %2)").arg(x).arg(y), WebPage::SafeJsWorld); runJavaScript(QSL("window.scrollTo(window.scrollX + %1, window.scrollY + %2)").arg(x).arg(y), SafeJsWorld);
} }
void WebPage::setScrollPosition(const QPointF &pos) void WebPage::setScrollPosition(const QPointF &pos)
{ {
const QPointF v = mapToViewport(pos.toPoint()); const QPointF v = mapToViewport(pos.toPoint());
runJavaScript(QSL("window.scrollTo(%1, %2)").arg(v.x()).arg(v.y()), WebPage::SafeJsWorld); runJavaScript(QSL("window.scrollTo(%1, %2)").arg(v.x()).arg(v.y()), SafeJsWorld);
} }
bool WebPage::isRunningLoop() bool WebPage::isRunningLoop()
@ -362,6 +360,20 @@ void WebPage::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationSt
}); });
} }
void WebPage::setupWebChannelForUrl(const QUrl &url)
{
QWebChannel *channel = webChannel();
if (!channel) {
channel = new QWebChannel(this);
ExternalJsObject::setupWebChannel(channel, this);
}
if (url.scheme() == QL1S("qupzilla")) {
setWebChannel(channel, UnsafeJsWorld);
} else {
setWebChannel(channel, SafeJsWorld);
}
}
bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame)
{ {
if (!mApp->plugins()->acceptNavigationRequest(this, url, type, isMainFrame)) if (!mApp->plugins()->acceptNavigationRequest(this, url, type, isMainFrame))
@ -373,6 +385,8 @@ bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::Navigatio
const bool isWeb = url.scheme() == QL1S("http") || url.scheme() == QL1S("https"); const bool isWeb = url.scheme() == QL1S("http") || url.scheme() == QL1S("https");
const bool globalJsEnabled = mApp->webSettings()->testAttribute(QWebEngineSettings::JavascriptEnabled); const bool globalJsEnabled = mApp->webSettings()->testAttribute(QWebEngineSettings::JavascriptEnabled);
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, isWeb ? globalJsEnabled : true); settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, isWeb ? globalJsEnabled : true);
setupWebChannelForUrl(url);
} }
return result; return result;

View File

@ -39,6 +39,7 @@ class FALKON_EXPORT WebPage : public QWebEnginePage
public: public:
enum JsWorld { enum JsWorld {
UnsafeJsWorld = QWebEngineScript::MainWorld,
SafeJsWorld = QWebEngineScript::ApplicationWorld SafeJsWorld = QWebEngineScript::ApplicationWorld
}; };
@ -48,7 +49,7 @@ public:
WebView *view() const; WebView *view() const;
bool execPrintPage(QPrinter *printer, int timeout = 1000); bool execPrintPage(QPrinter *printer, int timeout = 1000);
QVariant execJavaScript(const QString &scriptSource, quint32 worldId = QWebEngineScript::MainWorld, int timeout = 500); QVariant execJavaScript(const QString &scriptSource, quint32 worldId = UnsafeJsWorld, int timeout = 500);
QPointF mapToViewport(const QPointF &pos) const; QPointF mapToViewport(const QPointF &pos) const;
WebHitTestResult hitTestContent(const QPoint &pos) const; WebHitTestResult hitTestContent(const QPoint &pos) const;
@ -84,6 +85,7 @@ private slots:
void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode); void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
private: private:
void setupWebChannelForUrl(const QUrl &url);
bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE; bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
bool certificateError(const QWebEngineCertificateError &error) Q_DECL_OVERRIDE; bool certificateError(const QWebEngineCertificateError &error) Q_DECL_OVERRIDE;
QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE; QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE;

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* Falkon - Qt web browser * Falkon - Qt web browser
* Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -133,7 +133,7 @@ void SearchToolBar::searchText(const QString &text)
ui->lineEdit->style()->polish(ui->lineEdit); ui->lineEdit->style()->polish(ui->lineEdit);
// Clear selection // Clear selection
m_view->page()->runJavaScript(QSL("window.getSelection().empty();")); m_view->page()->runJavaScript(QSL("window.getSelection().empty();"), WebPage::SafeJsWorld);
}); });
} }

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* GreaseMonkey plugin for Falkon * GreaseMonkey plugin for Falkon
* Copyright (C) 2012-2017 David Rosca <nowrep@gmail.com> * Copyright (C) 2012-2018 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,9 +19,9 @@
#include "gm_manager.h" #include "gm_manager.h"
#include "gm_downloader.h" #include "gm_downloader.h"
#include "qzregexp.h"
#include "delayedfilewatcher.h" #include "delayedfilewatcher.h"
#include "mainapplication.h" #include "mainapplication.h"
#include "webpage.h"
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
@ -131,7 +131,7 @@ QWebEngineScript GM_Script::webScript() const
QWebEngineScript script; QWebEngineScript script;
script.setSourceCode(QSL("%1\n%2").arg(m_manager->bootstrapScript(), m_script)); script.setSourceCode(QSL("%1\n%2").arg(m_manager->bootstrapScript(), m_script));
script.setName(fullName()); script.setName(fullName());
script.setWorldId(QWebEngineScript::MainWorld); script.setWorldId(WebPage::SafeJsWorld);
script.setRunsOnSubFrames(!m_noframes); script.setRunsOnSubFrames(!m_noframes);
return script; return script;
} }