Browse Source

fix: pass frameId to v8Util.setRemoteCallbackFreer() (#20732) (#20813)

Milan Burda 5 years ago
parent
commit
a1fb069624

+ 1 - 1
lib/browser/remote/server.ts

@@ -309,7 +309,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
         v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
         Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
 
-        v8Util.setRemoteCallbackFreer(callIntoRenderer, contextId, meta.id, sender)
+        v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender)
         rendererFunctions.set(objectId, callIntoRenderer)
         return callIntoRenderer
       }

+ 12 - 4
shell/common/api/remote/remote_callback_freer.cc

@@ -16,29 +16,37 @@ namespace electron {
 // static
 void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
                                  v8::Local<v8::Object> target,
+                                 int frame_id,
                                  const std::string& context_id,
                                  int object_id,
                                  content::WebContents* web_contents) {
-  new RemoteCallbackFreer(isolate, target, context_id, object_id, web_contents);
+  new RemoteCallbackFreer(isolate, target, frame_id, context_id, object_id,
+                          web_contents);
 }
 
 RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
                                          v8::Local<v8::Object> target,
+                                         int frame_id,
                                          const std::string& context_id,
                                          int object_id,
                                          content::WebContents* web_contents)
     : ObjectLifeMonitor(isolate, target),
       content::WebContentsObserver(web_contents),
+      frame_id_(frame_id),
       context_id_(context_id),
       object_id_(object_id) {}
 
 RemoteCallbackFreer::~RemoteCallbackFreer() = default;
 
 void RemoteCallbackFreer::RunDestructor() {
-  auto* frame_host = web_contents()->GetMainFrame();
-  if (frame_host) {
+  auto frames = web_contents()->GetAllFrames();
+  auto iter = std::find_if(frames.begin(), frames.end(), [this](auto* f) {
+    return f->GetRoutingID() == frame_id_;
+  });
+
+  if (iter != frames.end() && (*iter)->IsRenderFrameLive()) {
     mojom::ElectronRendererAssociatedPtr electron_ptr;
-    frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
+    (*iter)->GetRemoteAssociatedInterfaces()->GetInterface(
         mojo::MakeRequest(&electron_ptr));
     electron_ptr->DereferenceRemoteJSCallback(context_id_, object_id_);
   }

+ 3 - 0
shell/common/api/remote/remote_callback_freer.h

@@ -17,6 +17,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
  public:
   static void BindTo(v8::Isolate* isolate,
                      v8::Local<v8::Object> target,
+                     int frame_id,
                      const std::string& context_id,
                      int object_id,
                      content::WebContents* web_conents);
@@ -24,6 +25,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
  protected:
   RemoteCallbackFreer(v8::Isolate* isolate,
                       v8::Local<v8::Object> target,
+                      int frame_id,
                       const std::string& context_id,
                       int object_id,
                       content::WebContents* web_conents);
@@ -35,6 +37,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
   void RenderViewDeleted(content::RenderViewHost*) override;
 
  private:
+  int frame_id_;
   std::string context_id_;
   int object_id_;
 

+ 1 - 1
typings/internal-ambient.d.ts

@@ -30,7 +30,7 @@ declare namespace NodeJS {
     deleteHiddenValue(obj: any, key: string): void;
     requestGarbageCollectionForTesting(): void;
     createDoubleIDWeakMap(): any;
-    setRemoteCallbackFreer(fn: Function, contextId: String, id: number, sender: any): void
+    setRemoteCallbackFreer(fn: Function, frameId: number, contextId: String, id: number, sender: any): void
   }
 
   interface Process {