fix: cross-origin navigation disposing WebFrameMain instances (#30076)
This commit is contained in:
		
					parent
					
						
							
								90b5ba3bed
							
						
					
				
			
			
				commit
				
					
						dd16d68e96
					
				
			
		
					 5 changed files with 150 additions and 96 deletions
				
			
		| 
						 | 
				
			
			@ -1384,7 +1384,9 @@ void WebContents::HandleNewRenderFrame(
 | 
			
		|||
  if (rwh_impl)
 | 
			
		||||
    rwh_impl->disable_hidden_ = !background_throttling_;
 | 
			
		||||
 | 
			
		||||
  WebFrameMain::RenderFrameCreated(render_frame_host);
 | 
			
		||||
  auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host);
 | 
			
		||||
  if (web_frame)
 | 
			
		||||
    web_frame->Connect();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::RenderFrameCreated(
 | 
			
		||||
| 
						 | 
				
			
			@ -1392,6 +1394,46 @@ void WebContents::RenderFrameCreated(
 | 
			
		|||
  HandleNewRenderFrame(render_frame_host);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::RenderFrameDeleted(
 | 
			
		||||
    content::RenderFrameHost* render_frame_host) {
 | 
			
		||||
  // A RenderFrameHost can be deleted when:
 | 
			
		||||
  // - A WebContents is removed and its containing frames are disposed.
 | 
			
		||||
  // - An <iframe> is removed from the DOM.
 | 
			
		||||
  // - Cross-origin navigation creates a new RFH in a separate process which
 | 
			
		||||
  //   is swapped by content::RenderFrameHostManager.
 | 
			
		||||
  //
 | 
			
		||||
  // WebFrameMain::FromRenderFrameHost(rfh) will use the RFH's FrameTreeNode ID
 | 
			
		||||
  // to find an existing instance of WebFrameMain. During a cross-origin
 | 
			
		||||
  // navigation, the deleted RFH will be the old host which was swapped out. In
 | 
			
		||||
  // this special case, we need to also ensure that WebFrameMain's internal RFH
 | 
			
		||||
  // matches before marking it as disposed.
 | 
			
		||||
  auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host);
 | 
			
		||||
  if (web_frame && web_frame->render_frame_host() == render_frame_host)
 | 
			
		||||
    web_frame->MarkRenderFrameDisposed();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::RenderFrameHostChanged(content::RenderFrameHost* old_host,
 | 
			
		||||
                                         content::RenderFrameHost* new_host) {
 | 
			
		||||
  // During cross-origin navigation, a FrameTreeNode will swap out its RFH.
 | 
			
		||||
  // If an instance of WebFrameMain exists, it will need to have its RFH
 | 
			
		||||
  // swapped as well.
 | 
			
		||||
  //
 | 
			
		||||
  // |old_host| can be a nullptr in so we use |new_host| for looking up the
 | 
			
		||||
  // WebFrameMain instance.
 | 
			
		||||
  auto* web_frame =
 | 
			
		||||
      WebFrameMain::FromFrameTreeNodeId(new_host->GetFrameTreeNodeId());
 | 
			
		||||
  if (web_frame) {
 | 
			
		||||
    CHECK_EQ(web_frame->render_frame_host(), old_host);
 | 
			
		||||
    web_frame->UpdateRenderFrameHost(new_host);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::FrameDeleted(int frame_tree_node_id) {
 | 
			
		||||
  auto* web_frame = WebFrameMain::FromFrameTreeNodeId(frame_tree_node_id);
 | 
			
		||||
  if (web_frame)
 | 
			
		||||
    web_frame->Destroyed();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
 | 
			
		||||
  // This event is necessary for tracking any states with respect to
 | 
			
		||||
  // intermediate render view hosts aka speculative render view hosts. Currently
 | 
			
		||||
| 
						 | 
				
			
			@ -1631,13 +1673,6 @@ void WebContents::UpdateDraggableRegions(
 | 
			
		|||
    observer.OnDraggableRegionsUpdated(regions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::RenderFrameDeleted(
 | 
			
		||||
    content::RenderFrameHost* render_frame_host) {
 | 
			
		||||
  // A WebFrameMain can outlive its RenderFrameHost so we need to mark it as
 | 
			
		||||
  // disposed to prevent access to it.
 | 
			
		||||
  WebFrameMain::RenderFrameDeleted(render_frame_host);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WebContents::DidStartNavigation(
 | 
			
		||||
    content::NavigationHandle* navigation_handle) {
 | 
			
		||||
  EmitNavigationEvent("did-start-navigation", navigation_handle);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue