fix: cross-origin navigation disposing WebFrameMain instances (#30076)

This commit is contained in:
Samuel Maddock 2021-08-18 14:23:41 -04:00 committed by GitHub
parent 90b5ba3bed
commit dd16d68e96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 150 additions and 96 deletions

View file

@ -31,6 +31,8 @@ namespace electron {
namespace api {
class WebContents;
// Bindings for accessing frames from the main process.
class WebFrameMain : public gin::Wrappable<WebFrameMain>,
public gin_helper::Pinnable<WebFrameMain>,
@ -39,23 +41,12 @@ class WebFrameMain : public gin::Wrappable<WebFrameMain>,
// Create a new WebFrameMain and return the V8 wrapper of it.
static gin::Handle<WebFrameMain> New(v8::Isolate* isolate);
static gin::Handle<WebFrameMain> FromID(v8::Isolate* isolate,
int render_process_id,
int render_frame_id);
static gin::Handle<WebFrameMain> From(
v8::Isolate* isolate,
content::RenderFrameHost* render_frame_host);
// Called to mark any RenderFrameHost as disposed by any WebFrameMain that
// may be holding a weak reference.
static void RenderFrameDeleted(content::RenderFrameHost* rfh);
static void RenderFrameCreated(content::RenderFrameHost* rfh);
// Mark RenderFrameHost as disposed and to no longer access it. This can
// occur upon frame navigation.
void MarkRenderFrameDisposed();
const mojo::Remote<mojom::ElectronRenderer>& GetRendererApi();
static WebFrameMain* FromFrameTreeNodeId(int frame_tree_node_id);
static WebFrameMain* FromRenderFrameHost(
content::RenderFrameHost* render_frame_host);
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
@ -64,11 +55,28 @@ class WebFrameMain : public gin::Wrappable<WebFrameMain>,
v8::Local<v8::ObjectTemplate>);
const char* GetTypeName() override;
content::RenderFrameHost* render_frame_host() const { return render_frame_; }
protected:
explicit WebFrameMain(content::RenderFrameHost* render_frame);
~WebFrameMain() override;
private:
friend class WebContents;
// Called when FrameTreeNode is deleted.
void Destroyed();
// Mark RenderFrameHost as disposed and to no longer access it. This can
// happen when the WebFrameMain v8 handle is GC'd or when a FrameTreeNode
// is removed.
void MarkRenderFrameDisposed();
// Swap out the internal RFH when cross-origin navigation occurs.
void UpdateRenderFrameHost(content::RenderFrameHost* rfh);
const mojo::Remote<mojom::ElectronRenderer>& GetRendererApi();
// WebFrameMain can outlive its RenderFrameHost pointer so we need to check
// whether its been disposed of prior to accessing it.
bool CheckRenderFrame() const;
@ -104,6 +112,8 @@ class WebFrameMain : public gin::Wrappable<WebFrameMain>,
mojo::Remote<mojom::ElectronRenderer> renderer_api_;
mojo::PendingReceiver<mojom::ElectronRenderer> pending_receiver_;
int frame_tree_node_id_;
content::RenderFrameHost* render_frame_ = nullptr;
// Whether the RenderFrameHost has been removed and that it should no longer