From dfb3b24de185f9c545f56f206c69a5b772da5853 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Wed, 10 Nov 2021 01:59:33 +0100 Subject: [PATCH] refactor: merge duplicate code from sandboxed/non-sandboxed renderer init (#31755) --- filenames.auto.gni | 2 + lib/renderer/common-init.ts | 64 +++++++++++++++++++++++++++++++ lib/renderer/init.ts | 61 +---------------------------- lib/renderer/security-warnings.ts | 2 +- lib/sandboxed_renderer/init.ts | 59 +--------------------------- 5 files changed, 71 insertions(+), 117 deletions(-) create mode 100644 lib/renderer/common-init.ts diff --git a/filenames.auto.gni b/filenames.auto.gni index 642d399d2e4..eb9632f19b8 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -143,6 +143,7 @@ auto_filenames = { "lib/renderer/api/crash-reporter.ts", "lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/web-frame.ts", + "lib/renderer/common-init.ts", "lib/renderer/inspector.ts", "lib/renderer/ipc-renderer-internal-utils.ts", "lib/renderer/ipc-renderer-internal.ts", @@ -272,6 +273,7 @@ auto_filenames = { "lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/module-list.ts", "lib/renderer/api/web-frame.ts", + "lib/renderer/common-init.ts", "lib/renderer/init.ts", "lib/renderer/inspector.ts", "lib/renderer/ipc-renderer-internal-utils.ts", diff --git a/lib/renderer/common-init.ts b/lib/renderer/common-init.ts new file mode 100644 index 00000000000..30ff1eb3425 --- /dev/null +++ b/lib/renderer/common-init.ts @@ -0,0 +1,64 @@ +import { ipcRenderer } from 'electron'; +import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'; + +import type * as webViewInitModule from '@electron/internal/renderer/web-view/web-view-init'; +import type * as windowSetupModule from '@electron/internal/renderer/window-setup'; +import type * as webFrameInitModule from '@electron/internal/renderer/web-frame-init'; +import type * as securityWarningsModule from '@electron/internal/renderer/security-warnings'; + +const { mainFrame } = process._linkedBinding('electron_renderer_web_frame'); +const v8Util = process._linkedBinding('electron_common_v8_util'); + +const nodeIntegration = mainFrame.getWebPreference('nodeIntegration'); +const webviewTag = mainFrame.getWebPreference('webviewTag'); +const isHiddenPage = mainFrame.getWebPreference('hiddenPage'); +const nativeWindowOpen = mainFrame.getWebPreference('nativeWindowOpen') || process.sandboxed; +const isWebView = mainFrame.getWebPreference('isWebView'); +const openerId = mainFrame.getWebPreference('openerId'); + +// ElectronApiServiceImpl will look for the "ipcNative" hidden object when +// invoking the 'onMessage' callback. +v8Util.setHiddenValue(global, 'ipcNative', { + onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number) { + if (internal && senderId !== 0) { + console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`); + return; + } + const sender = internal ? ipcRendererInternal : ipcRenderer; + sender.emit(channel, { sender, senderId, ports }, ...args); + } +}); + +switch (window.location.protocol) { + case 'devtools:': { + // Override some inspector APIs. + require('@electron/internal/renderer/inspector'); + break; + } + case 'chrome-extension:': { + break; + } + case 'chrome:': { + break; + } + default: { + // Override default web functions. + const { windowSetup } = require('@electron/internal/renderer/window-setup') as typeof windowSetupModule; + windowSetup(isWebView, openerId, isHiddenPage, nativeWindowOpen); + } +} + +// Load webview tag implementation. +if (process.isMainFrame) { + const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init') as typeof webViewInitModule; + webViewInit(webviewTag, isWebView); +} + +const { webFrameInit } = require('@electron/internal/renderer/web-frame-init') as typeof webFrameInitModule; +webFrameInit(); + +// Warn about security issues +if (process.isMainFrame) { + const { securityWarnings } = require('@electron/internal/renderer/security-warnings') as typeof securityWarningsModule; + securityWarnings(nodeIntegration); +} diff --git a/lib/renderer/init.ts b/lib/renderer/init.ts index b8b98863ef3..98073485689 100644 --- a/lib/renderer/init.ts +++ b/lib/renderer/init.ts @@ -2,10 +2,6 @@ import * as path from 'path'; import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; import type * as ipcRendererInternalModule from '@electron/internal/renderer/ipc-renderer-internal'; -import type * as webFrameInitModule from '@electron/internal/renderer/web-frame-init'; -import type * as webViewInitModule from '@electron/internal/renderer/web-view/web-view-init'; -import type * as windowSetupModule from '@electron/internal/renderer/window-setup'; -import type * as securityWarningsModule from '@electron/internal/renderer/security-warnings'; const Module = require('module'); @@ -36,49 +32,24 @@ Module.wrapper = [ process.argv.splice(1, 1); // Clear search paths. - require('../common/reset-search-paths'); // Import common settings. require('@electron/internal/common/init'); -// The global variable will be used by ipc for event dispatching -const v8Util = process._linkedBinding('electron_common_v8_util'); - const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal') as typeof ipcRendererInternalModule; -const ipcRenderer = require('@electron/internal/renderer/api/ipc-renderer').default; - -v8Util.setHiddenValue(global, 'ipcNative', { - onMessage (internal: boolean, channel: string, ports: any[], args: any[], senderId: number) { - if (internal && senderId !== 0) { - console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`); - return; - } - const sender = internal ? ipcRendererInternal : ipcRenderer; - sender.emit(channel, { sender, senderId, ports }, ...args); - } -}); process.getProcessMemoryInfo = () => { return ipcRendererInternal.invoke(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO); }; -// Use electron module after everything is ready. -const { webFrameInit } = require('@electron/internal/renderer/web-frame-init') as typeof webFrameInitModule; -webFrameInit(); - // Process command line arguments. const { hasSwitch, getSwitchValue } = process._linkedBinding('electron_common_command_line'); const { mainFrame } = process._linkedBinding('electron_renderer_web_frame'); const nodeIntegration = mainFrame.getWebPreference('nodeIntegration'); -const webviewTag = mainFrame.getWebPreference('webviewTag'); -const isHiddenPage = mainFrame.getWebPreference('hiddenPage'); -const usesNativeWindowOpen = mainFrame.getWebPreference('nativeWindowOpen'); const preloadScript = mainFrame.getWebPreference('preload'); const preloadScripts = mainFrame.getWebPreference('preloadScripts'); -const isWebView = mainFrame.getWebPreference('isWebView'); -const openerId = mainFrame.getWebPreference('openerId'); const appPath = hasSwitch('app-path') ? getSwitchValue('app-path') : null; // The webContents preload script is loaded after the session preload scripts. @@ -86,30 +57,8 @@ if (preloadScript) { preloadScripts.push(preloadScript); } -switch (window.location.protocol) { - case 'devtools:': { - // Override some inspector APIs. - require('@electron/internal/renderer/inspector'); - break; - } - case 'chrome-extension:': { - break; - } - case 'chrome:': { - break; - } - default: { - // Override default web functions. - const { windowSetup } = require('@electron/internal/renderer/window-setup') as typeof windowSetupModule; - windowSetup(isWebView, openerId, isHiddenPage, usesNativeWindowOpen); - } -} - -// Load webview tag implementation. -if (process.isMainFrame) { - const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init') as typeof webViewInitModule; - webViewInit(webviewTag, isWebView); -} +// Common renderer initialization +require('@electron/internal/renderer/common-init'); if (nodeIntegration) { // Export node bindings to global. @@ -189,9 +138,3 @@ for (const preloadScript of preloadScripts) { ipcRendererInternal.send(IPC_MESSAGES.BROWSER_PRELOAD_ERROR, preloadScript, error); } } - -// Warn about security issues -if (process.isMainFrame) { - const { securityWarnings } = require('@electron/internal/renderer/security-warnings') as typeof securityWarningsModule; - securityWarnings(nodeIntegration); -} diff --git a/lib/renderer/security-warnings.ts b/lib/renderer/security-warnings.ts index 5b5e0a7a367..30cb0cc63b6 100644 --- a/lib/renderer/security-warnings.ts +++ b/lib/renderer/security-warnings.ts @@ -281,7 +281,7 @@ const getWebPreferences = async function () { } }; -export function securityWarnings (nodeIntegration = false) { +export function securityWarnings (nodeIntegration: boolean) { const loadHandler = async function () { if (shouldLogSecurityWarnings()) { const webPreferences = await getWebPreferences(); diff --git a/lib/sandboxed_renderer/init.ts b/lib/sandboxed_renderer/init.ts index 4af61817b85..a9956759172 100644 --- a/lib/sandboxed_renderer/init.ts +++ b/lib/sandboxed_renderer/init.ts @@ -4,10 +4,6 @@ import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils'; import type * as ipcRendererInternalModule from '@electron/internal/renderer/ipc-renderer-internal'; -import type * as webFrameInitModule from '@electron/internal/renderer/web-frame-init'; -import type * as webViewInitModule from '@electron/internal/renderer/web-view/web-view-init'; -import type * as windowSetupModule from '@electron/internal/renderer/window-setup'; -import type * as securityWarningsModule from '@electron/internal/renderer/security-warnings'; const { EventEmitter } = events; @@ -45,19 +41,6 @@ const loadableModules = new Map([ ['url', () => require('url')] ]); -// ElectronApiServiceImpl will look for the "ipcNative" hidden object when -// invoking the 'onMessage' callback. -v8Util.setHiddenValue(global, 'ipcNative', { - onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number) { - if (internal && senderId !== 0) { - console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`); - return; - } - const sender = internal ? ipcRendererInternal : electron.ipcRenderer; - sender.emit(channel, { sender, senderId, ports }, ...args); - } -}); - // ElectronSandboxedRendererClient will look for the "lifecycle" hidden object when v8Util.setHiddenValue(global, 'lifecycle', { onLoaded () { @@ -74,9 +57,6 @@ v8Util.setHiddenValue(global, 'lifecycle', { } }); -const { webFrameInit } = require('@electron/internal/renderer/web-frame-init') as typeof webFrameInitModule; -webFrameInit(); - // Pass different process object to the preload script. const preloadProcess: NodeJS.Process = new EventEmitter() as any; @@ -119,7 +99,6 @@ function preloadRequire (module: string) { // Process command line arguments. const { hasSwitch } = process._linkedBinding('electron_common_command_line'); -const { mainFrame } = process._linkedBinding('electron_renderer_web_frame'); // Similar to nodes --expose-internals flag, this exposes _linkedBinding so // that tests can call it to get access to some test only bindings @@ -127,36 +106,8 @@ if (hasSwitch('unsafely-expose-electron-internals-for-testing')) { preloadProcess._linkedBinding = process._linkedBinding; } -const webviewTag = mainFrame.getWebPreference('webviewTag'); -const isHiddenPage = mainFrame.getWebPreference('hiddenPage'); -const usesNativeWindowOpen = true; -const isWebView = mainFrame.getWebPreference('isWebView'); -const openerId = mainFrame.getWebPreference('openerId'); - -switch (window.location.protocol) { - case 'devtools:': { - // Override some inspector APIs. - require('@electron/internal/renderer/inspector'); - break; - } - case 'chrome-extension:': { - break; - } - case 'chrome:': { - break; - } - default: { - // Override default web functions. - const { windowSetup } = require('@electron/internal/renderer/window-setup') as typeof windowSetupModule; - windowSetup(isWebView, openerId, isHiddenPage, usesNativeWindowOpen); - } -} - -// Load webview tag implementation. -if (process.isMainFrame) { - const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init') as typeof webViewInitModule; - webViewInit(webviewTag, isWebView); -} +// Common renderer initialization +require('@electron/internal/renderer/common-init'); // Wrap the script into a function executed in global scope. It won't have // access to the current scope, so we'll expose a few objects as arguments: @@ -191,9 +142,3 @@ for (const { preloadPath, preloadSrc, preloadError } of preloadScripts) { ipcRendererInternal.send(IPC_MESSAGES.BROWSER_PRELOAD_ERROR, preloadPath, error); } } - -// Warn about security issues -if (process.isMainFrame) { - const { securityWarnings } = require('@electron/internal/renderer/security-warnings') as typeof securityWarningsModule; - securityWarnings(); -}