summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-15 15:32:08 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-15 16:03:41 +0100
commitc69f510ed6e85c64f02ee0ee030336cd9aa66793 (patch)
treec2555af8f13b5336047e17548092bf1590f81576
parentaf30e7857e205990057735a07fe0974af9db8733 (diff)
parent74d2d301b11f2edfde69f0515e2fd74882ab6dab (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
-rw-r--r--dist/changes-5.12.178
-rw-r--r--src/core/api/qwebengineurlscheme.cpp33
-rw-r--r--src/core/api/qwebengineurlscheme.h4
-rw-r--r--src/core/content_client_qt.cpp14
-rw-r--r--src/core/ozone/gl_surface_glx_qt.cpp2
-rw-r--r--src/core/profile_io_data_qt.cpp169
-rw-r--r--src/core/profile_io_data_qt.h5
-rw-r--r--src/core/web_engine_context.cpp15
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp9
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc16
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc4
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp1
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp5
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp16
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp23
16 files changed, 284 insertions, 112 deletions
diff --git a/dist/changes-5.12.1 b/dist/changes-5.12.1
new file mode 100644
index 000000000..44dfdd5c7
--- /dev/null
+++ b/dist/changes-5.12.1
@@ -0,0 +1,78 @@
+Qt 5.12.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.12.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Qt 5.12.1 Changes *
+****************************************************************************
+
+Chromium
+--------
+
+ - Security fixes from Chromium up to version 71.0.3578.94, including:
+ * CVE-2018-17480
+ * CVE-2018-17481
+ * CVE-2018-18335
+ * CVE-2018-18336
+ * CVE-2018-18337
+ * CVE-2018-18338
+ * CVE-2018-18339
+ * CVE-2018-18340
+ * CVE-2018-18341
+ * CVE-2018-18342
+ * CVE-2018-18343
+ * CVE-2018-18345
+ * CVE-2018-18347
+ * CVE-2018-18349
+ * CVE-2018-18350
+ * CVE-2018-18355
+ * CVE-2018-18356
+ * CVE-2018-18357
+ * CVE-2018-18358
+ * CVE-2018-18359
+ * Security Bug 839250
+ * Security Bug 851821
+ * Security Bug 869067
+ * Security Bug 877843
+ * Security Bug 879965
+ * Security Bug 880665
+ * Security Bug 882270
+ * Security Bug 892643
+ * Security Bug 895885
+ * Security Bug 900910
+ - Fixed x86-32 builds on GCC 8.
+ - Fixed building on ARM hosts.
+
+
+General
+-------
+
+ * Enabled idle detection and sleep inhibition on Linux and macOS.
+ * [QTBUG-66262] Improved suggested file name of downloads when conflicts arise.
+ * [QTBUG-71322] Enabled bilinear filtering of textures in software rendering mode.
+ * [QTBUG-71370] Fixed autoscrolling regression.
+ * [QTBUG-71895] Fixed crash when calling clearHttpCache().
+ * [QTBUG-72260] Fixed crash on requestInterceptor changes.
+ * [QTBUG-72654] Fixed Event.timeStamp being 0.
+ * [QTBUG-72655] Fixed some JS properties of dead key event.
+
+
+QtQuickWebEngine
+----------------
+
+ * [QTBUG-72299] Fixed problem with blank view after reuse.
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index d63599163..9f7288f2d 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -39,7 +39,9 @@
#include "qwebengineurlscheme.h"
-#include <url/url_util_qt.h>
+#include "url/url_util_qt.h"
+
+#include <QtDebug>
QT_BEGIN_NAMESPACE
@@ -59,6 +61,8 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ServiceWorkersAllowed, url::CustomScheme
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ViewSourceAllowed, url::CustomScheme::ViewSourceAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ContentSecurityPolicyIgnored, url::CustomScheme::ContentSecurityPolicyIgnored)
+static bool g_schemesLocked = false;
+
class QWebEngineUrlSchemePrivate : public QSharedData
, public url::CustomScheme
{
@@ -357,6 +361,28 @@ void QWebEngineUrlScheme::setFlags(Flags newValue)
*/
void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme)
{
+ if (scheme.d->name.empty()) {
+ qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme name cannot be empty";
+ return;
+ }
+
+ bool needsPort = scheme.d->has_port_component();
+ bool hasPort = scheme.d->default_port != url::PORT_UNSPECIFIED;
+ if (needsPort && !hasPort) {
+ qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "needs a default port";
+ return;
+ }
+
+ if (url::CustomScheme::FindScheme(scheme.d->name)) {
+ qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "already registered";
+ return;
+ }
+
+ if (g_schemesLocked) {
+ qWarning() << "QWebEngineUrlScheme::registerScheme: Too late to register scheme" << scheme.name();
+ return;
+ }
+
url::CustomScheme::AddScheme(*scheme.d);
}
@@ -374,4 +400,9 @@ QWebEngineUrlScheme QWebEngineUrlScheme::schemeByName(const QByteArray &name)
return QWebEngineUrlScheme();
}
+void QWebEngineUrlScheme::lockSchemes()
+{
+ g_schemesLocked = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlscheme.h b/src/core/api/qwebengineurlscheme.h
index 88a8f5065..da3010335 100644
--- a/src/core/api/qwebengineurlscheme.h
+++ b/src/core/api/qwebengineurlscheme.h
@@ -46,6 +46,8 @@
#include <QtCore/qobjectdefs.h>
#include <QtCore/qshareddata.h>
+namespace QtWebEngineCore { class WebEngineContext; }
+
QT_BEGIN_NAMESPACE
class QWebEngineUrlSchemePrivate;
@@ -106,6 +108,8 @@ public:
static QWebEngineUrlScheme schemeByName(const QByteArray &name);
private:
+ friend QtWebEngineCore::WebEngineContext;
+ static void lockSchemes();
QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d);
QSharedDataPointer<QWebEngineUrlSchemePrivate> d;
};
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 9065174b8..9bfc8eede 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -288,9 +288,19 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
pluginPaths << ppapiPluginsPath() + QStringLiteral("/") + QString::fromLatin1(kWidevineCdmFileName);
#endif
#if defined(Q_OS_OSX)
- QDir potentialWidevineDir(QDir::homePath() + "/Library/Application Support/Google/Chrome/WidevineCDM");
+ QDir potentialWidevineDir("/Applications/Google Chrome.app/Contents/Versions");
if (potentialWidevineDir.exists()) {
- QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+ QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot,
+ QDir::Name | QDir::Reversed);
+ const QString library = QLatin1String("/Google Chrome Framework.framework/Versions/A/Libraries/"
+ "WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib");
+ for (const QFileInfo &info : widevineVersionDirs)
+ pluginPaths << info.absoluteFilePath() + library;
+ }
+
+ QDir oldPotentialWidevineDir(QDir::homePath() + "/Library/Application Support/Google/Chrome/WidevineCDM");
+ if (oldPotentialWidevineDir.exists()) {
+ QFileInfoList widevineVersionDirs = oldPotentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
for (int i = 0; i < widevineVersionDirs.size(); ++i) {
QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/mac_x64/" + QString::fromLatin1(kWidevineCdmFileName);
diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp
index eebefa59b..4faa08091 100644
--- a/src/core/ozone/gl_surface_glx_qt.cpp
+++ b/src/core/ozone/gl_surface_glx_qt.cpp
@@ -173,7 +173,7 @@ bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format)
GLX_PBUFFER_HEIGHT, m_size.height(),
GLX_LARGEST_PBUFFER, x11::False,
GLX_PRESERVED_CONTENTS, x11::False,
- GLX_NONE
+ NULL
};
m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes);
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index e44354029..01a4e98aa 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -189,6 +189,9 @@ ProfileIODataQt::~ProfileIODataQt()
#endif
}
+ if (m_urlRequestContext && m_urlRequestContext->proxy_resolution_service())
+ m_urlRequestContext->proxy_resolution_service()->OnShutdown();
+
m_resourceContext.reset();
if (m_cookieDelegate)
m_cookieDelegate->setCookieMonster(0); // this will let CookieMonsterDelegateQt be deleted
@@ -240,10 +243,10 @@ void ProfileIODataQt::initializeOnIOThread()
// this binds factory to io thread
m_weakPtr = m_weakPtrFactory.GetWeakPtr();
QMutexLocker lock(&m_mutex);
- m_initialized = true;
generateAllStorage();
generateJobFactory();
setGlobalCertificateVerification();
+ m_initialized = true;
}
void ProfileIODataQt::initializeOnUIThread()
@@ -258,6 +261,7 @@ void ProfileIODataQt::initializeOnUIThread()
protocolHandlerRegistry->CreateJobInterceptorFactory();
m_cookieDelegate = new CookieMonsterDelegateQt();
m_cookieDelegate->setClient(m_profile->profileAdapter()->cookieStore());
+ createProxyConfig();
}
void ProfileIODataQt::cancelAllUrlRequests()
@@ -293,11 +297,12 @@ void ProfileIODataQt::generateStorage()
// We must stop all requests before deleting their backends.
if (m_storage) {
- m_cookieDelegate->setCookieMonster(0);
- m_storage->set_cookie_store(0);
+ m_urlRequestContext->proxy_resolution_service()->OnShutdown();
+ m_cookieDelegate->setCookieMonster(nullptr);
+ m_storage->set_cookie_store(nullptr);
cancelAllUrlRequests();
// we need to get rid of dangling pointer due to coming storage deletion
- m_urlRequestContext->set_http_transaction_factory(0);
+ m_urlRequestContext->set_http_transaction_factory(nullptr);
m_httpNetworkSession.reset();
m_transportSecurityPersister.reset();
}
@@ -317,29 +322,23 @@ void ProfileIODataQt::generateStorage()
m_storage->set_cert_verifier(std::move(cert_verifier));
std::unique_ptr<net::MultiLogCTVerifier> ct_verifier(new net::MultiLogCTVerifier());
-// FIXME:
-// ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
+ std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs;
+ for (const auto &ct_log : certificate_transparency::GetKnownLogs()) {
+ scoped_refptr<const net::CTLogVerifier> log_verifier =
+ net::CTLogVerifier::Create(std::string(ct_log.log_key, ct_log.log_key_length),
+ ct_log.log_name,
+ ct_log.log_dns_domain);
+ if (!log_verifier)
+ continue;
+ ct_logs.push_back(std::move(log_verifier));
+ }
+ ct_verifier->AddLogs(ct_logs);
m_storage->set_cert_transparency_verifier(std::move(ct_verifier));
m_storage->set_ct_policy_enforcer(base::WrapUnique(new net::DefaultCTPolicyEnforcer()));
-
- std::unique_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
-
- // The System Proxy Resolver has issues on Windows with unconfigured network cards,
- // which is why we want to use the v8 one
- if (!m_dhcpPacFileFetcherFactory)
- m_dhcpPacFileFetcherFactory.reset(new net::DhcpPacFileFetcherFactory);
-
- proxy_resolver::mojom::ProxyResolverFactoryPtr proxyResolver(std::move(m_proxyResolverFactoryInterface));
- m_storage->set_proxy_resolution_service(network::CreateProxyResolutionServiceUsingMojoFactory(
- std::move(proxyResolver),
- std::unique_ptr<net::ProxyConfigService>(proxyConfigService),
- net::PacFileFetcherImpl::CreateWithFileUrlSupport(m_urlRequestContext.get()),
- m_dhcpPacFileFetcherFactory->Create(m_urlRequestContext.get()),
- host_resolver.get(),
- nullptr /* NetLog */,
- m_networkDelegate.get()));
-
+ m_storage->set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
m_storage->set_ssl_config_service(std::make_unique<net::SSLConfigServiceDefaults>());
+ m_storage->set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault(
+ m_urlRequestContext->host_resolver()));
m_storage->set_transport_security_state(std::make_unique<net::TransportSecurityState>());
if (!m_dataPath.isEmpty()) {
@@ -355,20 +354,23 @@ void ProfileIODataQt::generateStorage()
background_task_runner);
};
- if (!m_httpAuthPreferences)
- m_httpAuthPreferences.reset(new net::HttpAuthPreferences());
-
- m_storage->set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault(
- host_resolver.get(),
- m_httpAuthPreferences.get()
-#if (defined(OS_POSIX) && !defined(OS_ANDROID)) || defined(OS_FUCHSIA)
- , std::string() /* gssapi library name */
-#endif
- ));
m_storage->set_http_server_properties(std::unique_ptr<net::HttpServerProperties>(
new net::HttpServerPropertiesImpl));
- // Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
- m_storage->set_host_resolver(std::move(host_resolver));
+
+ // The System Proxy Resolver has issues on Windows with unconfigured network cards,
+ // which is why we want to use the v8 one
+ if (!m_dhcpPacFileFetcherFactory)
+ m_dhcpPacFileFetcherFactory.reset(new net::DhcpPacFileFetcherFactory);
+
+ proxy_resolver::mojom::ProxyResolverFactoryPtr proxyResolver(std::move(m_proxyResolverFactoryInterface));
+ m_storage->set_proxy_resolution_service(network::CreateProxyResolutionServiceUsingMojoFactory(
+ std::move(proxyResolver),
+ std::unique_ptr<net::ProxyConfigService>(proxyConfigService),
+ net::PacFileFetcherImpl::CreateWithFileUrlSupport(m_urlRequestContext.get()),
+ m_dhcpPacFileFetcherFactory->Create(m_urlRequestContext.get()),
+ m_urlRequestContext->host_resolver(),
+ nullptr /* NetLog */,
+ m_urlRequestContext->network_delegate()));
}
@@ -376,10 +378,8 @@ void ProfileIODataQt::generateCookieStore()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_urlRequestContext);
- Q_ASSERT(m_storage);
QMutexLocker lock(&m_mutex);
- m_updateCookieStore = false;
scoped_refptr<net::SQLiteChannelIDStore> channel_id_db;
if (!m_channelIdPath.isEmpty() && m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies) {
@@ -393,11 +393,6 @@ void ProfileIODataQt::generateCookieStore()
base::WrapUnique(new net::ChannelIDService(
new net::DefaultChannelIDStore(channel_id_db.get()))));
- // Unset it first to get a chance to destroy and flush the old cookie store before
- // opening a new on possibly the same file.
- m_cookieDelegate->setCookieMonster(0);
- m_storage->set_cookie_store(0);
-
std::unique_ptr<net::CookieStore> cookieStore;
switch (m_persistentCookiesPolicy) {
case ProfileAdapter::NoPersistentCookies:
@@ -437,11 +432,6 @@ void ProfileIODataQt::generateCookieStore()
const std::vector<std::string> cookieableSchemes(kCookieableSchemes,
kCookieableSchemes + arraysize(kCookieableSchemes));
cookieMonster->SetCookieableSchemes(cookieableSchemes);
-
- if (!m_updateAllStorage && m_updateHttpCache) {
- // HttpCache needs to be regenerated when we generate a new channel id service
- generateHttpCache();
- }
}
void ProfileIODataQt::generateUserAgent()
@@ -451,8 +441,6 @@ void ProfileIODataQt::generateUserAgent()
Q_ASSERT(m_storage);
QMutexLocker lock(&m_mutex);
- m_updateUserAgent = false;
-
m_storage->set_http_user_agent_settings(std::unique_ptr<net::HttpUserAgentSettings>(
new net::StaticHttpUserAgentSettings(m_httpAcceptLanguage.toStdString(),
m_httpUserAgent.toStdString())));
@@ -465,10 +453,6 @@ void ProfileIODataQt::generateHttpCache()
Q_ASSERT(m_storage);
QMutexLocker lock(&m_mutex);
- m_updateHttpCache = false;
-
- if (m_updateCookieStore)
- generateCookieStore();
net::HttpCache::DefaultBackend* main_backend = 0;
switch (m_httpCacheType) {
@@ -635,6 +619,38 @@ void ProfileIODataQt::setFullConfiguration()
m_dataPath = m_profileAdapter->dataPath();
}
+void ProfileIODataQt::requestStorageGeneration() {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ if (m_initialized && !m_updateAllStorage) {
+ m_updateAllStorage = true;
+ createProxyConfig();
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&ProfileIODataQt::generateAllStorage, m_weakPtr));
+ }
+}
+
+// TODO(miklocek): mojofy ProxyConfigServiceQt
+void ProfileIODataQt::createProxyConfig()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ // We must create the proxy config service on the UI loop on Linux because it
+ // must synchronously run on the glib message loop. This will be passed to
+ // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
+ Q_ASSERT(m_proxyConfigService == 0);
+ net::ProxyConfigWithAnnotation initialConfig;
+ ProxyPrefs::ConfigState initialConfigState = PrefProxyConfigTrackerImpl::ReadPrefConfig(
+ m_profileAdapter->profile()->GetPrefs(), &initialConfig);
+ m_proxyConfigService =
+ new ProxyConfigServiceQt(
+ net::ProxyResolutionService::CreateSystemProxyConfigService(
+ base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})),
+ initialConfig, initialConfigState);
+ //pass interface to io thread
+ m_proxyResolverFactoryInterface = ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface();
+}
+
void ProfileIODataQt::updateStorageSettings()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
@@ -647,28 +663,7 @@ void ProfileIODataQt::updateStorageSettings()
file::ForgetServiceUserIdUserDirAssociation(userId);
file::AssociateServiceUserIdWithUserDir(userId, toFilePath(m_profileAdapter->dataPath()));
}
-
- if (!m_updateAllStorage) {
- m_updateAllStorage = true;
- // We must create the proxy config service on the UI loop on Linux because it
- // must synchronously run on the glib message loop. This will be passed to
- // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
- Q_ASSERT(m_proxyConfigService == 0);
- net::ProxyConfigWithAnnotation initialConfig;
- ProxyPrefs::ConfigState initialConfigState = PrefProxyConfigTrackerImpl::ReadPrefConfig(
- m_profileAdapter->profile()->GetPrefs(), &initialConfig);
-
- m_proxyConfigService =
- new ProxyConfigServiceQt(
- net::ProxyResolutionService::CreateSystemProxyConfigService(
- base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})),
- initialConfig, initialConfigState);
- //pass interface to io thread
- m_proxyResolverFactoryInterface = ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface();
- if (m_initialized)
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&ProfileIODataQt::generateAllStorage, m_weakPtr));
- }
+ requestStorageGeneration();
}
void ProfileIODataQt::updateCookieStore()
@@ -678,13 +673,7 @@ void ProfileIODataQt::updateCookieStore()
m_persistentCookiesPolicy = m_profileAdapter->persistentCookiesPolicy();
m_cookiesPath = m_profileAdapter->cookiesPath();
m_channelIdPath = m_profileAdapter->channelIdPath();
-
- if (m_initialized && !m_updateAllStorage && !m_updateCookieStore) {
- m_updateCookieStore = true;
- m_updateHttpCache = true;
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&ProfileIODataQt::generateCookieStore, m_weakPtr));
- }
+ requestStorageGeneration();
}
void ProfileIODataQt::updateUserAgent()
@@ -693,12 +682,7 @@ void ProfileIODataQt::updateUserAgent()
QMutexLocker lock(&m_mutex);
m_httpAcceptLanguage = m_profileAdapter->httpAcceptLanguage();
m_httpUserAgent = m_profileAdapter->httpUserAgent();
-
- if (m_initialized && !m_updateAllStorage && !m_updateUserAgent) {
- m_updateUserAgent = true;
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&ProfileIODataQt::generateUserAgent, m_weakPtr));
- }
+ requestStorageGeneration();
}
void ProfileIODataQt::updateHttpCache()
@@ -717,12 +701,7 @@ void ProfileIODataQt::updateHttpCache()
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);
}
-
- if (m_initialized && !m_updateAllStorage && !m_updateHttpCache) {
- m_updateHttpCache = true;
- base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&ProfileIODataQt::generateHttpCache, m_weakPtr));
- }
+ requestStorageGeneration();
}
void ProfileIODataQt::updateJobFactory()
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 4694ae350..b983b3a99 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -118,6 +118,8 @@ public:
void updateHttpCache(); // runs on ui thread
void updateJobFactory(); // runs on ui thread
void updateRequestInterceptor(); // runs on ui thread
+ void requestStorageGeneration(); //runs on ui thread
+ void createProxyConfig(); //runs on ui thread
void updateUsedForGlobalCertificateVerification(); // runs on ui thread
bool hasPageInterceptors();
@@ -157,10 +159,7 @@ private:
int m_httpCacheMaxSize = 0;
bool m_initialized = false;
bool m_updateAllStorage = false;
- bool m_updateCookieStore = false;
- bool m_updateHttpCache = false;
bool m_updateJobFactory = false;
- bool m_updateUserAgent = false;
bool m_ignoreCertificateErrors = false;
bool m_useForGlobalCertificateVerification = false;
bool m_hasPageInterceptors = false;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 63a1637fe..67639dc4f 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -368,11 +368,16 @@ WebEngineContext::WebEngineContext()
qputenv("force_s3tc_enable", "true");
#endif
- QWebEngineUrlScheme qrcScheme(QByteArrayLiteral("qrc"));
- qrcScheme.setFlags(QWebEngineUrlScheme::SecureScheme
- | QWebEngineUrlScheme::LocalAccessAllowed
- | QWebEngineUrlScheme::ViewSourceAllowed);
- QWebEngineUrlScheme::registerScheme(qrcScheme);
+ if (QWebEngineUrlScheme::schemeByName(QByteArrayLiteral("qrc")) == QWebEngineUrlScheme()) {
+ // User might have registered "qrc" already with different options.
+ QWebEngineUrlScheme qrcScheme(QByteArrayLiteral("qrc"));
+ qrcScheme.setFlags(QWebEngineUrlScheme::SecureScheme
+ | QWebEngineUrlScheme::LocalAccessAllowed
+ | QWebEngineUrlScheme::ViewSourceAllowed);
+ QWebEngineUrlScheme::registerScheme(qrcScheme);
+ }
+
+ QWebEngineUrlScheme::lockSchemes();
// Allow us to inject javascript like any webview toolkit.
content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index ba7e99c47..e756ee157 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -63,7 +63,7 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
setFocus(true);
setActiveFocusOnTab(true);
-#ifdef Q_OS_OSX
+#if defined(Q_OS_MACOS) && !defined(QT_NO_OPENGL)
// Check that the default QSurfaceFormat OpenGL profile is compatible with the global OpenGL
// shared context profile, otherwise this could lead to a nasty crash.
QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext();
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 790d802f0..a1ddf88d7 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -2382,6 +2382,10 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &page
The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array
will contain the PDF data, otherwise, the byte array will be empty.
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
\since 5.7
*/
void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &pageLayout)
@@ -2414,6 +2418,11 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
The \a resultCallback must take a boolean as parameter. If printing was successful, this
boolean will have the value \c true, otherwise, its value will be \c false.
+
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
\since 5.8
*/
void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 427668a11..877bf7175 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -487,6 +487,10 @@
The \a resultCallback must take a boolean parameter. It will be called with a value of \c true
if the \a subString was found; otherwise the callback value will be \c false.
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
For example:
\snippet qtwebengine_qwebenginepage_snippet.cpp 0
*/
@@ -615,6 +619,10 @@
\note \a resultCallback can be any of a function pointer, a functor or a lambda, and it is expected to take a QString parameter.
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
\sa setHtml(), toPlainText()
*/
@@ -626,6 +634,10 @@
\note \a resultCallback can be any of a function pointer, a functor or a lambda, and it is expected to take a QString parameter.
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
\sa toHtml()
*/
@@ -745,6 +757,10 @@
\warning Do not execute lengthy routines in the callback function, because it might block the
rendering of the web engine page.
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
See scripts() for an alternative API to inject scripts.
\sa QWebEngineScript::ScriptWorldId
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 09346a446..501959ab9 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -252,6 +252,10 @@
\a resultCallback must take a boolean parameter. It will be called with a value of \c true
if \a subString was found; otherwise the callback value will be \c false.
+ \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
+ during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
+ value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
+
\sa selectedText(), selectionChanged()
*/
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index efdfb17d0..951360c05 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -277,6 +277,7 @@ void RenderWidgetHostViewQtDelegateWidget::show()
void RenderWidgetHostViewQtDelegateWidget::hide()
{
m_rootItem->setVisible(false);
+ QQuickWidget::hide();
}
bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index 61c7232b0..61d16bc8a 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -637,10 +637,7 @@ void tst_Origins::sharedWorker()
QTRY_VERIFY(eval(QSL("done")).toBool());
QCOMPARE(eval(QSL("result")), QVariant(42));
- // Even unregistered schemes can create SharedWorkers.
- QVERIFY(load(QSL("tst:/resources/sharedWorker.html")));
- QTRY_VERIFY(eval(QSL("done")).toBool());
- QCOMPARE(eval(QSL("result")), QVariant(42));
+ // Unregistered schemes should not create SharedWorkers.
QVERIFY(load(QSL("PathSyntax:/resources/sharedWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index bf5d320b7..b0db4e974 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -31,6 +31,7 @@
#include <QtTest/QtTest>
#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineCore/qwebengineurlrequestjob.h>
+#include <QtWebEngineCore/qwebenginecookiestore.h>
#include <QtWebEngineCore/qwebengineurlschemehandler.h>
#include <QtWebEngineWidgets/qwebengineprofile.h>
#include <QtWebEngineWidgets/qwebenginepage.h>
@@ -59,6 +60,7 @@ private Q_SLOTS:
void downloadItem();
void changePersistentPath();
void initiator();
+ void qtbug_72299(); // this should be the last test
};
void tst_QWebEngineProfile::init()
@@ -629,5 +631,19 @@ void tst_QWebEngineProfile::initiator()
QCOMPARE(handler.initiator, QUrl());
}
+void tst_QWebEngineProfile::qtbug_72299()
+{
+ QWebEngineView view;
+ view.setUrl(QUrl("https://www.qt.io"));
+ view.show();
+ QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
+ view.page()->profile()->clearHttpCache();
+ view.page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache);
+ view.page()->profile()->cookieStore()->deleteAllCookies();
+ view.page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+}
+
+
QTEST_MAIN(tst_QWebEngineProfile)
#include "tst_qwebengineprofile.moc"
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index f2810101b..17177c7fb 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -46,6 +46,7 @@
#include <QTcpSocket>
#include <QStyle>
#include <QtWidgets/qaction.h>
+#include <QWebEngineProfile>
#include <QtCore/qregularexpression.h>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
@@ -194,6 +195,7 @@ private Q_SLOTS:
void jsKeyboardEvent();
void deletePage();
void closeOpenerTab();
+ void switchPage();
};
// This will be called before the first test function is executed.
@@ -3174,5 +3176,26 @@ void tst_QWebEngineView::closeOpenerTab()
QVERIFY(newView->focusProxy()->isVisible());
}
+void tst_QWebEngineView::switchPage()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page1(&profile);
+ QWebEnginePage page2(&profile);
+ QSignalSpy loadFinishedSpy1(&page1, SIGNAL(loadFinished(bool)));
+ QSignalSpy loadFinishedSpy2(&page2, SIGNAL(loadFinished(bool)));
+ page1.setHtml("<html><body bgcolor=\"#000000\"></body></html>");
+ page2.setHtml("<html><body bgcolor=\"#ffffff\"></body></html>");
+ QTRY_VERIFY(loadFinishedSpy1.count() && loadFinishedSpy2.count());
+ QWebEngineView webView;
+ webView.resize(300,300);
+ webView.show();
+ webView.setPage(&page1);
+ QTRY_COMPARE(webView.grab().toImage().pixelColor(QPoint(150,150)), Qt::black);
+ webView.setPage(&page2);
+ QTRY_COMPARE(webView.grab().toImage().pixelColor(QPoint(150,150)), Qt::white);
+ webView.setPage(&page1);
+ QTRY_COMPARE(webView.grab().toImage().pixelColor(QPoint(150,150)), Qt::black);
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"