diff options
author | Michal Klocek <michal.klocek@qt.io> | 2018-03-20 21:11:36 +0000 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2018-06-05 14:19:39 +0000 |
commit | 9a660be58f3e46e45351b2edd790b897bf1772a0 (patch) | |
tree | ae8517f2389a2da4faa1e3f44b2a45e87f332f0a | |
parent | ae56fd7445a474743d9820ddfdf5d50d00ebec3c (diff) |
[Backport] CVE-2018-6135
Force a flush of drawing to the widget when a dialog is shown.
BUG=823353
TEST=as in bug
Reviewed-on: https://chromium-review.googlesource.com/971661
Change-Id: I83fae12fdb6e43cb3ad06f8484d552790f4831c6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
3 files changed, 40 insertions, 0 deletions
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc index 04f3f40e770..c1a8af784c3 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc @@ -686,6 +686,10 @@ void RenderWidgetHostImpl::WasShown(const ui::LatencyInfo& latency_info) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::WasShown"); is_hidden_ = false; + // If we navigated in background, clear the displayed graphics of the + // previous page before going visible. + ForceFirstFrameAfterNavigationTimeout(); + SendScreenRects(); RestartHangMonitorTimeoutIfNecessary(); @@ -2943,6 +2947,15 @@ void RenderWidgetHostImpl::ProgressFling(base::TimeTicks current_time) { input_router_->ProgressFling(current_time); } +void RenderWidgetHostImpl::ForceFirstFrameAfterNavigationTimeout() { + if (new_content_rendering_timeout_ && + new_content_rendering_timeout_->IsRunning()) { + new_content_rendering_timeout_->Stop(); + ClearDisplayedGraphics(); + } +} + + void RenderWidgetHostImpl::StopFling() { if (input_router_) input_router_->StopFling(); diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h index bfaf957de69..e1a44a87568 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.h +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h @@ -639,6 +639,13 @@ class CONTENT_EXPORT RenderWidgetHostImpl void ProgressFling(base::TimeTicks current_time); void StopFling(); + // The RenderWidgetHostImpl will keep showing the old page (for a while) after + // navigation until the first frame of the new page arrives. This reduces + // flicker. However, if for some reason it is known that the frames won't be + // arriving, this call can be used for force a timeout, to avoid showing the + // content of the old page under UI from the new page. + void ForceFirstFrameAfterNavigationTimeout(); + protected: // --------------------------------------------------------------------------- // The following method is overridden by RenderViewHost to send upwards to diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc index 0e4799f4441..675a0ab4e00 100644 --- a/chromium/content/browser/web_contents/web_contents_impl.cc +++ b/chromium/content/browser/web_contents/web_contents_impl.cc @@ -4613,6 +4613,16 @@ void WebContentsImpl::RunJavaScriptDialog(RenderFrameHost* render_frame_host, const GURL& frame_url, JavaScriptDialogType dialog_type, IPC::Message* reply_msg) { + // Ensure that if showing a dialog is the first thing that a page does, that + // the contents of the previous page aren't shown behind it. This is required + // because showing a dialog freezes the renderer, so no frames will be coming + // from it. https://crbug.com/823353 + auto* render_widget_host_impl = + static_cast<RenderFrameHostImpl*>(render_frame_host) + ->GetRenderWidgetHost(); + if (render_widget_host_impl) + render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout(); + // Running a dialog causes an exit to webpage-initiated fullscreen. // http://crbug.com/728276 if (IsFullscreenForCurrentTab()) @@ -4671,6 +4681,16 @@ void WebContentsImpl::RunBeforeUnloadConfirm( RenderFrameHost* render_frame_host, bool is_reload, IPC::Message* reply_msg) { + // Ensure that if showing a dialog is the first thing that a page does, that + // the contents of the previous page aren't shown behind it. This is required + // because showing a dialog freezes the renderer, so no frames will be coming + // from it. https://crbug.com/823353 + auto* render_widget_host_impl = + static_cast<RenderFrameHostImpl*>(render_frame_host) + ->GetRenderWidgetHost(); + if (render_widget_host_impl) + render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout(); + // Running a dialog causes an exit to webpage-initiated fullscreen. // http://crbug.com/728276 if (IsFullscreenForCurrentTab()) |