summaryrefslogtreecommitdiffstats
path: root/src/webenginewidgets/api/qwebengineprofile.cpp
diff options
context:
space:
mode:
authorKirill Burtsev <kirill.burtsev@qt.io>2019-02-11 19:21:03 +0100
committerKirill Burtsev <kirill.burtsev@qt.io>2019-02-19 15:30:44 +0000
commit7537526093c92e89672d1e952a9baceecaa91730 (patch)
treedcb37c57802b90eff5835f54f13ef6a8db059ac7 /src/webenginewidgets/api/qwebengineprofile.cpp
parent755f7e414583c5458c2d421d047a1c7890c8d8d2 (diff)
Remove download properly on profile destruction to avoid use after free
In the Widgets API, download items are children of the profile and are destroyed when the parent profile destroys its children. The download item's destructor can therefore not access the profile, as it would cause a heap-use-after-free crashes. On quick side turn ongoing downloads cleanup to match widgets one. Fixes: QTBUG-73839 Change-Id: Iabb379e91187e3e68ebcd4693fec35883b72b1f2 Reviewed-by: Michael Brüning <michael.bruning@qt.io> Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'src/webenginewidgets/api/qwebengineprofile.cpp')
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 03ce5e0bc..0d12fdae1 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -175,13 +175,6 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
m_profileAdapter->removeClient(this);
}
- for (QWebEngineDownloadItem *download : qAsConst(m_ongoingDownloads)) {
- if (download)
- download->cancel();
- }
-
- m_ongoingDownloads.clear();
-
if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter())
delete m_profileAdapter;
@@ -196,6 +189,23 @@ ProfileAdapter* QWebEngineProfilePrivate::profileAdapter() const
void QWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
{
m_ongoingDownloads.remove(downloadId);
+ if (m_profileAdapter)
+ m_profileAdapter->removeDownload(downloadId);
+}
+
+void QWebEngineProfilePrivate::cleanDownloads()
+{
+ for (auto download : m_ongoingDownloads.values()) {
+ if (!download)
+ continue;
+
+ if (!download->isFinished())
+ download->cancel();
+
+ if (m_profileAdapter)
+ m_profileAdapter->removeDownload(download->id());
+ }
+ m_ongoingDownloads.clear();
}
void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
@@ -219,6 +229,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
QWebEngineDownloadItem *download = new QWebEngineDownloadItem(itemPrivate, q);
m_ongoingDownloads.insert(info.id, download);
+ QObject::connect(download, &QWebEngineDownloadItem::destroyed, q, [id = info.id, this] () { downloadDestroyed(id); });
Q_EMIT q->downloadRequested(download);
@@ -232,7 +243,6 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
if (state == QWebEngineDownloadItem::DownloadRequested) {
// Delete unaccepted downloads.
info.accepted = false;
- m_ongoingDownloads.remove(info.id);
delete download;
}
}
@@ -250,9 +260,6 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
}
download->d_func()->update(info);
-
- if (download->isFinished())
- m_ongoingDownloads.remove(info.id);
}
/*!
@@ -301,6 +308,7 @@ QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr, QObje
*/
QWebEngineProfile::~QWebEngineProfile()
{
+ d_ptr->cleanDownloads();
}
/*!