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: expose native bindings by process type #37175

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 docs/development/creating-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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})
```

Expand Down
61 changes: 41 additions & 20 deletions shell/common/node_bindings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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) \
Expand Down Expand Up @@ -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)

Expand All @@ -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
Expand Down Expand Up @@ -370,13 +379,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
Expand Down
43 changes: 43 additions & 0 deletions spec/internal-spec.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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\')');
});
});
});