From 1e11575a32685f7ac01f8b0cd425fa8d3ce3de33 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Wed, 22 Aug 2018 16:12:38 +0200 Subject: [PATCH] Avoid reattach of page before deleting it Also fixes potential double delete if you do delete a view's implied page. Change-Id: Ib74128c0801f992694f4a5d8c148974039a6c7b2 Reviewed-by: Michal Klocek <michal.klocek@qt.io> Reviewed-by: Zakor Tamas <ztamas@inf.u-szeged.hu> --- src/webenginewidgets/api/qwebenginepage.cpp | 2 +- src/webenginewidgets/api/qwebengineview.cpp | 15 ++++++++------- src/webenginewidgets/api/qwebengineview_p.h | 2 +- .../widgets/qwebengineview/tst_qwebengineview.cpp | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 96468f173..a86681191 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -902,7 +902,7 @@ QWebEnginePage::~QWebEnginePage() Q_D(QWebEnginePage); setDevToolsPage(nullptr); d->adapter->stopFinding(); - QWebEngineViewPrivate::bind(d->view, 0); + QWebEngineViewPrivate::bind(nullptr, this, true); } QWebEngineHistory *QWebEnginePage::history() const diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index a207af392..aa51e5b0e 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE -void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page) +void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page, bool pageBeingDeleted) { if (view && page == view->d_func()->page) return; @@ -64,20 +64,22 @@ void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page) // Un-bind page from its current view. if (QWebEngineView *oldView = page->d_func()->view) { page->disconnect(oldView); - oldView->d_func()->page = 0; + oldView->d_func()->page = nullptr; } page->d_func()->view = view; - page->d_func()->adapter->reattachRWHV(); + if (!pageBeingDeleted) + page->d_func()->adapter->reattachRWHV(); } if (view) { // Un-bind view from its current page. if (QWebEnginePage *oldPage = view->d_func()->page) { oldPage->disconnect(view); - oldPage->d_func()->view = 0; - oldPage->d_func()->adapter->reattachRWHV(); + oldPage->d_func()->view = nullptr; if (oldPage->parent() == view) delete oldPage; + else + oldPage->d_func()->adapter->reattachRWHV(); } view->d_func()->page = page; } @@ -147,8 +149,7 @@ QWebEngineView::QWebEngineView(QWidget *parent) QWebEngineView::~QWebEngineView() { - Q_D(QWebEngineView); - QWebEngineViewPrivate::bind(0, d->page); + QWebEngineViewPrivate::bind(this, nullptr); } QWebEnginePage* QWebEngineView::page() const diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h index 7f0cdac45..bfb44bec5 100644 --- a/src/webenginewidgets/api/qwebengineview_p.h +++ b/src/webenginewidgets/api/qwebengineview_p.h @@ -65,7 +65,7 @@ public: Q_DECLARE_PUBLIC(QWebEngineView) QWebEngineView *q_ptr; - static void bind(QWebEngineView *view, QWebEnginePage *page); + static void bind(QWebEngineView *view, QWebEnginePage *page, bool pageBeingDeleted = false); QWebEngineViewPrivate(); diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 5f30fa6b9..1499a5f05 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -188,6 +188,7 @@ private Q_SLOTS: void webUIURLs(); void visibilityState(); void jsKeyboardEvent(); + void deletePage(); }; // This will be called before the first test function is executed. @@ -2793,5 +2794,19 @@ void tst_QWebEngineView::jsKeyboardEvent() QCOMPARE(evaluateJavaScriptSync(view.page(), "log"), expected); } +void tst_QWebEngineView::deletePage() +{ + QWebEngineView view; + QWebEnginePage *page = view.page(); + QVERIFY(page); + QCOMPARE(page->parent(), &view); + delete page; + // Test that a new page is created and that it is useful: + QVERIFY(view.page()); + QSignalSpy spy(view.page(), &QWebEnginePage::loadFinished); + view.page()->load(QStringLiteral("about:blank")); + QTRY_VERIFY(spy.count()); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" -- GitLab