Browse Source

fix: expose native bindings by process type (#37176)

* fix: expose native bindings by process type

Co-authored-by: Milan Burda <[email protected]>

* fix test

* fix test

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <[email protected]>
trop[bot] 2 years ago
parent
commit
c781daaa6a
3 changed files with 85 additions and 21 deletions
  1. 1 1
      docs/development/creating-api.md
  2. 41 20
      shell/common/node_bindings.cc
  3. 43 0
      spec/internal-spec.ts

+ 1 - 1
docs/development/creating-api.md

@@ -144,7 +144,7 @@ NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
 In your [`shell/common/node_bindings.cc`](https://github.com/electron/electron/blob/main/shell/common/node_bindings.cc) file, add your node binding name to Electron's built-in modules.
 
 ```cpp title='shell/common/node_bindings.cc'
-#define ELECTRON_BUILTIN_MODULES(V)      \
+#define ELECTRON_BROWSER_MODULES(V)      \
   V(electron_browser_{api_name})
 ```
 

+ 41 - 20
shell/common/node_bindings.cc

@@ -24,6 +24,7 @@
 #include "base/trace_event/trace_event.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
 #include "electron/buildflags/buildflags.h"
 #include "electron/fuses.h"
 #include "shell/browser/api/electron_api_app.h"
@@ -43,7 +44,7 @@
 #include "shell/common/crash_keys.h"
 #endif
 
-#define ELECTRON_BUILTIN_MODULES(V)      \
+#define ELECTRON_BROWSER_MODULES(V)      \
   V(electron_browser_app)                \
   V(electron_browser_auto_updater)       \
   V(electron_browser_browser_view)       \
@@ -76,21 +77,26 @@
   V(electron_browser_web_contents_view)  \
   V(electron_browser_web_frame_main)     \
   V(electron_browser_web_view_manager)   \
-  V(electron_browser_window)             \
-  V(electron_common_asar)                \
-  V(electron_common_clipboard)           \
-  V(electron_common_command_line)        \
-  V(electron_common_crashpad_support)    \
-  V(electron_common_environment)         \
-  V(electron_common_features)            \
-  V(electron_common_native_image)        \
-  V(electron_common_shell)               \
-  V(electron_common_v8_util)             \
-  V(electron_renderer_context_bridge)    \
-  V(electron_renderer_crash_reporter)    \
-  V(electron_renderer_ipc)               \
-  V(electron_renderer_web_frame)         \
-  V(electron_utility_parent_port)
+  V(electron_browser_window)
+
+#define ELECTRON_COMMON_MODULES(V)    \
+  V(electron_common_asar)             \
+  V(electron_common_clipboard)        \
+  V(electron_common_command_line)     \
+  V(electron_common_crashpad_support) \
+  V(electron_common_environment)      \
+  V(electron_common_features)         \
+  V(electron_common_native_image)     \
+  V(electron_common_shell)            \
+  V(electron_common_v8_util)
+
+#define ELECTRON_RENDERER_MODULES(V)  \
+  V(electron_renderer_context_bridge) \
+  V(electron_renderer_crash_reporter) \
+  V(electron_renderer_ipc)            \
+  V(electron_renderer_web_frame)
+
+#define ELECTRON_UTILITY_MODULES(V) V(electron_utility_parent_port)
 
 #define ELECTRON_VIEWS_MODULES(V) V(electron_browser_image_view)
 
@@ -104,7 +110,10 @@
 // forward declaration. The definitions are in each module's
 // implementation when calling the NODE_LINKED_MODULE_CONTEXT_AWARE.
 #define V(modname) void _register_##modname();
-ELECTRON_BUILTIN_MODULES(V)
+ELECTRON_BROWSER_MODULES(V)
+ELECTRON_COMMON_MODULES(V)
+ELECTRON_RENDERER_MODULES(V)
+ELECTRON_UTILITY_MODULES(V)
 #if BUILDFLAG(ENABLE_VIEWS_API)
 ELECTRON_VIEWS_MODULES(V)
 #endif
@@ -330,13 +339,25 @@ NodeBindings::~NodeBindings() {
 
 void NodeBindings::RegisterBuiltinModules() {
 #define V(modname) _register_##modname();
-  ELECTRON_BUILTIN_MODULES(V)
+  auto* command_line = base::CommandLine::ForCurrentProcess();
+  std::string process_type =
+      command_line->GetSwitchValueASCII(::switches::kProcessType);
+  if (process_type.empty()) {
+    ELECTRON_BROWSER_MODULES(V)
 #if BUILDFLAG(ENABLE_VIEWS_API)
-  ELECTRON_VIEWS_MODULES(V)
+    ELECTRON_VIEWS_MODULES(V)
 #endif
 #if BUILDFLAG(ENABLE_DESKTOP_CAPTURER)
-  ELECTRON_DESKTOP_CAPTURER_MODULE(V)
+    ELECTRON_DESKTOP_CAPTURER_MODULE(V)
 #endif
+  }
+  ELECTRON_COMMON_MODULES(V)
+  if (process_type == ::switches::kRendererProcess) {
+    ELECTRON_RENDERER_MODULES(V)
+  }
+  if (process_type == ::switches::kUtilityProcess) {
+    ELECTRON_UTILITY_MODULES(V)
+  }
 #if DCHECK_IS_ON()
   ELECTRON_TESTING_MODULE(V)
 #endif

+ 43 - 0
spec/internal-spec.ts

@@ -1,4 +1,6 @@
 import { expect } from 'chai';
+import { BrowserWindow } from 'electron/main';
+import { closeAllWindows } from './window-helpers';
 
 describe('feature-string parsing', () => {
   it('is indifferent to whitespace around keys and values', () => {
@@ -19,3 +21,44 @@ describe('feature-string parsing', () => {
     checkParse(' a = yes , c = d ', { a: true, c: 'd' });
   });
 });
+
+describe('process._linkedBinding', () => {
+  describe('in the main process', () => {
+    it('can access electron_browser bindings', () => {
+      process._linkedBinding('electron_browser_app');
+    });
+
+    it('can access electron_common bindings', () => {
+      process._linkedBinding('electron_common_v8_util');
+    });
+
+    it('cannot access electron_renderer bindings', () => {
+      expect(() => {
+        process._linkedBinding('electron_renderer_ipc');
+      }).to.throw(/No such module was linked: electron_renderer_ipc/);
+    });
+  });
+
+  describe('in the renderer process', () => {
+    afterEach(closeAllWindows);
+
+    it('cannot access electron_browser bindings', async () => {
+      const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
+      w.loadURL('about:blank');
+      await expect(w.webContents.executeJavaScript('void process._linkedBinding(\'electron_browser_app\')'))
+        .to.eventually.be.rejectedWith(/Script failed to execute/);
+    });
+
+    it('can access electron_common bindings', async () => {
+      const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
+      w.loadURL('about:blank');
+      await w.webContents.executeJavaScript('void process._linkedBinding(\'electron_common_v8_util\')');
+    });
+
+    it('can access electron_renderer bindings', async () => {
+      const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
+      w.loadURL('about:blank');
+      await w.webContents.executeJavaScript('void process._linkedBinding(\'electron_renderer_ipc\')');
+    });
+  });
+});