From cf06b687845b6e37ef3cd80fd644bb7d769f0033 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Wed, 27 Sep 2017 10:24:05 +0200 Subject: Stabilize navigation after render process termination When renderProcessTerminated signal is emitted the invalid view of the corresponding RenderWidgetHost is not destructed yet. Having this invalid view during navigation leads to a crash. The proper way to navigate on renderProcessTerminated is to schedule the navigation with QTimer::singleShot(). Otherwise, warn the user and ignore navigation to avoid crash. Task-number: QTBUG-58478 Change-Id: I54ff62f5d306c8cb1fa17e29f349d1e02c4c8cec Reviewed-by: Allan Sandfeld Jensen --- src/core/render_widget_host_view_qt.cpp | 2 ++ src/core/web_contents_adapter.cpp | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 655871c9c..466d2826b 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -927,6 +927,8 @@ void RenderWidgetHostViewQt::windowChanged() bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) { + Q_ASSERT(m_host->GetView()); + switch (event->type()) { case QEvent::MouseButtonPress: Focus(); // Fall through. diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 1f0c996ef..a5e33257e 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -102,6 +102,12 @@ namespace QtWebEngineCore { +#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \ + if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \ + qWarning("Ignore navigation due to terminated render process with invalid RenderWidgetHostView."); \ + return; \ + } + static const int kTestWindowWidth = 800; static const int kTestWindowHeight = 600; static const int kHistoryStreamVersion = 3; @@ -501,6 +507,7 @@ void WebContentsAdapter::stop() void WebContentsAdapter::reload() { Q_D(WebContentsAdapter); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost()); d->webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false); focusIfNecessary(); } @@ -508,6 +515,7 @@ void WebContentsAdapter::reload() void WebContentsAdapter::reloadAndBypassCache() { Q_D(WebContentsAdapter); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost()); d->webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false); focusIfNecessary(); } @@ -520,6 +528,9 @@ void WebContentsAdapter::load(const QUrl &url) void WebContentsAdapter::load(const QWebEngineHttpRequest &request) { + Q_D(WebContentsAdapter); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost()); + // The situation can occur when relying on the editingFinished signal in QML to set the url // of the WebView. // When enter is pressed, onEditingFinished fires and the url of the webview is set, which @@ -533,7 +544,6 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) LoadRecursionGuard guard(this); Q_UNUSED(guard); - Q_D(WebContentsAdapter); GURL gurl = toGurl(request.url()); // Add URL scheme if missing from view-source URL. @@ -590,6 +600,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl) { Q_D(WebContentsAdapter); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost()); + QByteArray encodedData = data.toPercentEncoding(); std::string urlString("data:"); urlString.append(mimeType.toStdString()); @@ -724,6 +736,7 @@ void WebContentsAdapter::unselect() void WebContentsAdapter::navigateToIndex(int offset) { Q_D(WebContentsAdapter); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost()); d->webContents->GetController().GoToIndex(offset); focusIfNecessary(); } @@ -731,6 +744,7 @@ void WebContentsAdapter::navigateToIndex(int offset) void WebContentsAdapter::navigateToOffset(int offset) { Q_D(WebContentsAdapter); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost()); d->webContents->GetController().GoToOffset(offset); focusIfNecessary(); } -- cgit v1.2.3