Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: crash when creating interface for speculative frame #34294

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -1510,7 +1510,7 @@ void WebContents::HandleNewRenderFrame(

auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host);
if (web_frame)
web_frame->Connect();
web_frame->MaybeSetupMojoConnection();
}

void WebContents::OnBackgroundColorChanged() {
Expand Down
33 changes: 19 additions & 14 deletions shell/browser/api/electron_api_web_frame_main.cc
Expand Up @@ -96,13 +96,15 @@ void WebFrameMain::Destroyed() {
void WebFrameMain::MarkRenderFrameDisposed() {
render_frame_ = nullptr;
render_frame_disposed_ = true;
TeardownMojoConnection();
}

void WebFrameMain::UpdateRenderFrameHost(content::RenderFrameHost* rfh) {
// Should only be called when swapping frames.
render_frame_disposed_ = false;
render_frame_ = rfh;
renderer_api_.reset();
TeardownMojoConnection();
MaybeSetupMojoConnection();
}

bool WebFrameMain::CheckRenderFrame() const {
Expand Down Expand Up @@ -182,20 +184,30 @@ void WebFrameMain::Send(v8::Isolate* isolate,
}

const mojo::Remote<mojom::ElectronRenderer>& WebFrameMain::GetRendererApi() {
MaybeSetupMojoConnection();
return renderer_api_;
}

void WebFrameMain::MaybeSetupMojoConnection() {
if (!renderer_api_) {
pending_receiver_ = renderer_api_.BindNewPipeAndPassReceiver();
if (render_frame_->IsRenderFrameCreated()) {
render_frame_->GetRemoteInterfaces()->GetInterface(
std::move(pending_receiver_));
}
renderer_api_.set_disconnect_handler(base::BindOnce(
&WebFrameMain::OnRendererConnectionError, weak_factory_.GetWeakPtr()));
}
return renderer_api_;
// Wait for RenderFrame to be created in renderer before accessing remote.
if (pending_receiver_ && render_frame_->IsRenderFrameCreated()) {
render_frame_->GetRemoteInterfaces()->GetInterface(
std::move(pending_receiver_));
}
}

void WebFrameMain::OnRendererConnectionError() {
void WebFrameMain::TeardownMojoConnection() {
renderer_api_.reset();
pending_receiver_.reset();
}

void WebFrameMain::OnRendererConnectionError() {
TeardownMojoConnection();
}

void WebFrameMain::PostMessage(v8::Isolate* isolate,
Expand Down Expand Up @@ -315,13 +327,6 @@ std::vector<content::RenderFrameHost*> WebFrameMain::FramesInSubtree() const {
return frame_hosts;
}

void WebFrameMain::Connect() {
if (pending_receiver_) {
render_frame_->GetRemoteInterfaces()->GetInterface(
std::move(pending_receiver_));
}
}

void WebFrameMain::DOMContentLoaded() {
Emit("dom-ready");
}
Expand Down
5 changes: 3 additions & 2 deletions shell/browser/api/electron_api_web_frame_main.h
Expand Up @@ -82,6 +82,9 @@ class WebFrameMain : public gin::Wrappable<WebFrameMain>,
void UpdateRenderFrameHost(content::RenderFrameHost* rfh);

const mojo::Remote<mojom::ElectronRenderer>& GetRendererApi();
void MaybeSetupMojoConnection();
void TeardownMojoConnection();
void OnRendererConnectionError();

// WebFrameMain can outlive its RenderFrameHost pointer so we need to check
// whether its been disposed of prior to accessing it.
Expand Down Expand Up @@ -112,8 +115,6 @@ class WebFrameMain : public gin::Wrappable<WebFrameMain>,
std::vector<content::RenderFrameHost*> Frames() const;
std::vector<content::RenderFrameHost*> FramesInSubtree() const;

void OnRendererConnectionError();
void Connect();
void DOMContentLoaded();

mojo::Remote<mojom::ElectronRenderer> renderer_api_;
Expand Down