diff options
author | Kirill Burtsev <kirill.burtsev@qt.io> | 2019-02-11 19:21:03 +0100 |
---|---|---|
committer | Kirill Burtsev <kirill.burtsev@qt.io> | 2019-02-19 15:30:44 +0000 |
commit | 7537526093c92e89672d1e952a9baceecaa91730 (patch) | |
tree | dcb37c57802b90eff5835f54f13ef6a8db059ac7 /src/webengine/api/qquickwebengineprofile.cpp | |
parent | 755f7e414583c5458c2d421d047a1c7890c8d8d2 (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/webengine/api/qquickwebengineprofile.cpp')
-rw-r--r-- | src/webengine/api/qquickwebengineprofile.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index ddc71602b..26fcf28f7 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -175,13 +175,6 @@ QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate() m_profileAdapter->removeClient(this); } - for (QQuickWebEngineDownloadItem *download : qAsConst(m_ongoingDownloads)) { - if (download) - download->cancel(); - } - - m_ongoingDownloads.clear(); - if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter()) delete m_profileAdapter; } @@ -215,6 +208,23 @@ void QQuickWebEngineProfilePrivate::cancelDownload(quint32 downloadId) void QQuickWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId) { m_ongoingDownloads.remove(downloadId); + if (m_profileAdapter) + m_profileAdapter->removeDownload(downloadId); +} + +void QQuickWebEngineProfilePrivate::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 QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) @@ -239,6 +249,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q); m_ongoingDownloads.insert(info.id, download); + QObject::connect(download, &QQuickWebEngineDownloadItem::destroyed, q, [id = info.id, this] () { downloadDestroyed(id); }); QQmlEngine::setObjectOwnership(download, QQmlEngine::JavaScriptOwnership); Q_EMIT q->downloadRequested(download); @@ -252,7 +263,6 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) if (state == QQuickWebEngineDownloadItem::DownloadRequested) { // Delete unaccepted downloads. info.accepted = false; - m_ongoingDownloads.remove(info.id); delete download; } } @@ -275,7 +285,6 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info if (info.state != ProfileAdapterClient::DownloadInProgress) { Q_EMIT q->downloadFinished(download); - m_ongoingDownloads.remove(info.id); } } @@ -380,6 +389,7 @@ QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *pr */ QQuickWebEngineProfile::~QQuickWebEngineProfile() { + d_ptr->cleanDownloads(); } /*! |