Browse Source

fix: prevent crash on web-contents creation when error is thrown (#29106)

* fix: prevent crash when error occurs during event emitter CallMethod

* wip: emit error event within trycatch

* fix: handle uncaught exceptions within node on web_contents init

* fix: create gin_helper::CallMethodCatchException

* test: add web-contents create crash to test cases

* test: clean up test data for web-contents crash

Co-authored-by: Jeremy Rose <[email protected]>

* fix: convert CatchException to WebContents static helper method

* fix: restore try_catch to callsite

Co-authored-by: VerteDinde <[email protected]>
Co-authored-by: VerteDinde <[email protected]>
Co-authored-by: Keeley Hammond <[email protected]>
Co-authored-by: Jeremy Rose <[email protected]>
trop[bot] 3 years ago
parent
commit
caac2e8fc7

+ 12 - 0
shell/browser/api/electron_api_web_contents.cc

@@ -3712,7 +3712,11 @@ gin::Handle<WebContents> WebContents::New(
     const gin_helper::Dictionary& options) {
   gin::Handle<WebContents> handle =
       gin::CreateHandle(isolate, new WebContents(isolate, options));
+  v8::TryCatch try_catch(isolate);
   gin_helper::CallMethod(isolate, handle.get(), "_init");
+  if (try_catch.HasCaught()) {
+    node::errors::TriggerUncaughtException(isolate, try_catch);
+  }
   return handle;
 }
 
@@ -3723,7 +3727,11 @@ gin::Handle<WebContents> WebContents::CreateAndTake(
     Type type) {
   gin::Handle<WebContents> handle = gin::CreateHandle(
       isolate, new WebContents(isolate, std::move(web_contents), type));
+  v8::TryCatch try_catch(isolate);
   gin_helper::CallMethod(isolate, handle.get(), "_init");
+  if (try_catch.HasCaught()) {
+    node::errors::TriggerUncaughtException(isolate, try_catch);
+  }
   return handle;
 }
 
@@ -3743,7 +3751,11 @@ gin::Handle<WebContents> WebContents::FromOrCreate(
   WebContents* api_web_contents = From(web_contents);
   if (!api_web_contents) {
     api_web_contents = new WebContents(isolate, web_contents);
+    v8::TryCatch try_catch(isolate);
     gin_helper::CallMethod(isolate, api_web_contents, "_init");
+    if (try_catch.HasCaught()) {
+      node::errors::TriggerUncaughtException(isolate, try_catch);
+    }
   }
   return gin::CreateHandle(isolate, api_web_contents);
 }

+ 1 - 0
shell/common/node_includes.h

@@ -64,6 +64,7 @@
 #include "env.h"
 #include "node.h"
 #include "node_buffer.h"
+#include "node_errors.h"
 #include "node_internals.h"
 #include "node_options-inl.h"
 #include "node_options.h"

+ 14 - 0
spec-main/fixtures/crash-cases/webview-contents-error-on-creation/index.js

@@ -0,0 +1,14 @@
+const { app, BrowserWindow } = require('electron');
+
+app.whenReady().then(() => {
+  const mainWindow = new BrowserWindow({
+    show: false
+  });
+  mainWindow.loadFile('about:blank');
+
+  app.on('web-contents-created', () => {
+    throw new Error();
+  });
+
+  app.quit();
+});