src: add kNoBrowserGlobals flag for Environment
PR-URL: https://github.com/nodejs/node/pull/40532 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
parent
f34c0e0bc0
commit
a706342368
@ -703,7 +703,8 @@ parser.add_argument('--no-browser-globals',
|
||||
dest='no_browser_globals',
|
||||
default=None,
|
||||
help='do not export browser globals like setTimeout, console, etc. ' +
|
||||
'(This mode is not officially supported for regular applications)')
|
||||
'(This mode is deprecated and not officially supported for regular ' +
|
||||
'applications)')
|
||||
|
||||
parser.add_argument('--without-inspector',
|
||||
action='store_true',
|
||||
|
118
lib/internal/bootstrap/browser.js
Normal file
118
lib/internal/bootstrap/browser.js
Normal file
@ -0,0 +1,118 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
ObjectDefineProperty,
|
||||
globalThis,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
defineOperation,
|
||||
exposeInterface,
|
||||
lazyDOMExceptionClass,
|
||||
} = require('internal/util');
|
||||
const config = internalBinding('config');
|
||||
|
||||
// Override global console from the one provided by the VM
|
||||
// to the one implemented by Node.js
|
||||
// https://console.spec.whatwg.org/#console-namespace
|
||||
exposeNamespace(globalThis, 'console',
|
||||
createGlobalConsole(globalThis.console));
|
||||
|
||||
const { URL, URLSearchParams } = require('internal/url');
|
||||
// https://url.spec.whatwg.org/#url
|
||||
exposeInterface(globalThis, 'URL', URL);
|
||||
// https://url.spec.whatwg.org/#urlsearchparams
|
||||
exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
|
||||
exposeGetterAndSetter(globalThis,
|
||||
'DOMException',
|
||||
lazyDOMExceptionClass,
|
||||
(value) => {
|
||||
exposeInterface(globalThis, 'DOMException', value);
|
||||
});
|
||||
|
||||
const {
|
||||
TextEncoder, TextDecoder
|
||||
} = require('internal/encoding');
|
||||
// https://encoding.spec.whatwg.org/#textencoder
|
||||
exposeInterface(globalThis, 'TextEncoder', TextEncoder);
|
||||
// https://encoding.spec.whatwg.org/#textdecoder
|
||||
exposeInterface(globalThis, 'TextDecoder', TextDecoder);
|
||||
|
||||
const {
|
||||
AbortController,
|
||||
AbortSignal,
|
||||
} = require('internal/abort_controller');
|
||||
exposeInterface(globalThis, 'AbortController', AbortController);
|
||||
exposeInterface(globalThis, 'AbortSignal', AbortSignal);
|
||||
|
||||
const {
|
||||
EventTarget,
|
||||
Event,
|
||||
} = require('internal/event_target');
|
||||
exposeInterface(globalThis, 'EventTarget', EventTarget);
|
||||
exposeInterface(globalThis, 'Event', Event);
|
||||
const {
|
||||
MessageChannel,
|
||||
MessagePort,
|
||||
MessageEvent,
|
||||
} = require('internal/worker/io');
|
||||
exposeInterface(globalThis, 'MessageChannel', MessageChannel);
|
||||
exposeInterface(globalThis, 'MessagePort', MessagePort);
|
||||
exposeInterface(globalThis, 'MessageEvent', MessageEvent);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
|
||||
const timers = require('timers');
|
||||
defineOperation(globalThis, 'clearInterval', timers.clearInterval);
|
||||
defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
|
||||
defineOperation(globalThis, 'setInterval', timers.setInterval);
|
||||
defineOperation(globalThis, 'setTimeout', timers.setTimeout);
|
||||
|
||||
// https://www.w3.org/TR/hr-time-2/#the-performance-attribute
|
||||
defineReplacableAttribute(globalThis, 'performance',
|
||||
require('perf_hooks').performance);
|
||||
|
||||
function createGlobalConsole(consoleFromVM) {
|
||||
const consoleFromNode =
|
||||
require('internal/console/global');
|
||||
if (config.hasInspector) {
|
||||
const inspector = require('internal/util/inspector');
|
||||
// This will be exposed by `require('inspector').console` later.
|
||||
inspector.consoleFromVM = consoleFromVM;
|
||||
// TODO(joyeecheung): postpone this until the first time inspector
|
||||
// is activated.
|
||||
inspector.wrapConsole(consoleFromNode, consoleFromVM);
|
||||
const { setConsoleExtensionInstaller } = internalBinding('inspector');
|
||||
// Setup inspector command line API.
|
||||
setConsoleExtensionInstaller(inspector.installConsoleExtensions);
|
||||
}
|
||||
return consoleFromNode;
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#es-namespaces
|
||||
function exposeNamespace(target, name, namespaceObject) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: namespaceObject
|
||||
});
|
||||
}
|
||||
|
||||
function exposeGetterAndSetter(target, name, getter, setter = undefined) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
get: getter,
|
||||
set: setter,
|
||||
});
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#Replaceable
|
||||
function defineReplacableAttribute(target, name, value) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value,
|
||||
});
|
||||
}
|
@ -56,7 +56,11 @@ const {
|
||||
} = primordials;
|
||||
const config = internalBinding('config');
|
||||
const internalTimers = require('internal/timers');
|
||||
const { deprecate, lazyDOMExceptionClass } = require('internal/util');
|
||||
const {
|
||||
defineOperation,
|
||||
deprecate,
|
||||
exposeInterface,
|
||||
} = require('internal/util');
|
||||
|
||||
setupProcessObject();
|
||||
|
||||
@ -205,79 +209,20 @@ const {
|
||||
queueMicrotask
|
||||
} = require('internal/process/task_queues');
|
||||
|
||||
if (!config.noBrowserGlobals) {
|
||||
// Override global console from the one provided by the VM
|
||||
// to the one implemented by Node.js
|
||||
// https://console.spec.whatwg.org/#console-namespace
|
||||
exposeNamespace(globalThis, 'console',
|
||||
createGlobalConsole(globalThis.console));
|
||||
// Non-standard extensions:
|
||||
const { BroadcastChannel } = require('internal/worker/io');
|
||||
exposeInterface(globalThis, 'BroadcastChannel', BroadcastChannel);
|
||||
|
||||
const { URL, URLSearchParams } = require('internal/url');
|
||||
// https://url.spec.whatwg.org/#url
|
||||
exposeInterface(globalThis, 'URL', URL);
|
||||
// https://url.spec.whatwg.org/#urlsearchparams
|
||||
exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
|
||||
exposeGetterAndSetter(globalThis,
|
||||
'DOMException',
|
||||
lazyDOMExceptionClass,
|
||||
(value) => {
|
||||
exposeInterface(globalThis, 'DOMException', value);
|
||||
});
|
||||
defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
|
||||
|
||||
const {
|
||||
TextEncoder, TextDecoder
|
||||
} = require('internal/encoding');
|
||||
// https://encoding.spec.whatwg.org/#textencoder
|
||||
exposeInterface(globalThis, 'TextEncoder', TextEncoder);
|
||||
// https://encoding.spec.whatwg.org/#textdecoder
|
||||
exposeInterface(globalThis, 'TextDecoder', TextDecoder);
|
||||
const timers = require('timers');
|
||||
defineOperation(globalThis, 'clearImmediate', timers.clearImmediate);
|
||||
defineOperation(globalThis, 'setImmediate', timers.setImmediate);
|
||||
|
||||
const {
|
||||
AbortController,
|
||||
AbortSignal,
|
||||
} = require('internal/abort_controller');
|
||||
exposeInterface(globalThis, 'AbortController', AbortController);
|
||||
exposeInterface(globalThis, 'AbortSignal', AbortSignal);
|
||||
|
||||
const {
|
||||
EventTarget,
|
||||
Event,
|
||||
} = require('internal/event_target');
|
||||
exposeInterface(globalThis, 'EventTarget', EventTarget);
|
||||
exposeInterface(globalThis, 'Event', Event);
|
||||
const {
|
||||
MessageChannel,
|
||||
MessagePort,
|
||||
MessageEvent,
|
||||
BroadcastChannel,
|
||||
} = require('internal/worker/io');
|
||||
exposeInterface(globalThis, 'MessageChannel', MessageChannel);
|
||||
exposeInterface(globalThis, 'MessagePort', MessagePort);
|
||||
exposeInterface(globalThis, 'MessageEvent', MessageEvent);
|
||||
exposeInterface(globalThis, 'BroadcastChannel', BroadcastChannel);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
|
||||
const timers = require('timers');
|
||||
defineOperation(globalThis, 'clearInterval', timers.clearInterval);
|
||||
defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
|
||||
defineOperation(globalThis, 'setInterval', timers.setInterval);
|
||||
defineOperation(globalThis, 'setTimeout', timers.setTimeout);
|
||||
|
||||
defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
|
||||
|
||||
// https://www.w3.org/TR/hr-time-2/#the-performance-attribute
|
||||
defineReplacableAttribute(globalThis, 'performance',
|
||||
require('perf_hooks').performance);
|
||||
|
||||
// Non-standard extensions:
|
||||
defineOperation(globalThis, 'clearImmediate', timers.clearImmediate);
|
||||
defineOperation(globalThis, 'setImmediate', timers.setImmediate);
|
||||
|
||||
const {
|
||||
structuredClone,
|
||||
} = require('internal/structured_clone');
|
||||
defineOperation(globalThis, 'structuredClone', structuredClone);
|
||||
}
|
||||
const {
|
||||
structuredClone,
|
||||
} = require('internal/structured_clone');
|
||||
defineOperation(globalThis, 'structuredClone', structuredClone);
|
||||
|
||||
// Set the per-Environment callback that will be called
|
||||
// when the TrackingTraceStateObserver updates trace state.
|
||||
@ -483,69 +428,3 @@ function setupBuffer() {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function createGlobalConsole(consoleFromVM) {
|
||||
const consoleFromNode =
|
||||
require('internal/console/global');
|
||||
if (config.hasInspector) {
|
||||
const inspector = require('internal/util/inspector');
|
||||
// This will be exposed by `require('inspector').console` later.
|
||||
inspector.consoleFromVM = consoleFromVM;
|
||||
// TODO(joyeecheung): postpone this until the first time inspector
|
||||
// is activated.
|
||||
inspector.wrapConsole(consoleFromNode, consoleFromVM);
|
||||
const { setConsoleExtensionInstaller } = internalBinding('inspector');
|
||||
// Setup inspector command line API.
|
||||
setConsoleExtensionInstaller(inspector.installConsoleExtensions);
|
||||
}
|
||||
return consoleFromNode;
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#es-namespaces
|
||||
function exposeNamespace(target, name, namespaceObject) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: namespaceObject
|
||||
});
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#es-interfaces
|
||||
function exposeInterface(target, name, interfaceObject) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: interfaceObject
|
||||
});
|
||||
}
|
||||
|
||||
function exposeGetterAndSetter(target, name, getter, setter = undefined) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
get: getter,
|
||||
set: setter,
|
||||
});
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#define-the-operations
|
||||
function defineOperation(target, name, method) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: method
|
||||
});
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#Replaceable
|
||||
function defineReplacableAttribute(target, name, value) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
@ -466,6 +466,26 @@ function createDeferredPromise() {
|
||||
return { promise, resolve, reject };
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#define-the-operations
|
||||
function defineOperation(target, name, method) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: method
|
||||
});
|
||||
}
|
||||
|
||||
// https://heycam.github.io/webidl/#es-interfaces
|
||||
function exposeInterface(target, name, interfaceObject) {
|
||||
ObjectDefineProperty(target, name, {
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: interfaceObject
|
||||
});
|
||||
}
|
||||
|
||||
let _DOMException;
|
||||
const lazyDOMExceptionClass = () => {
|
||||
_DOMException ??= internalBinding('messaging').DOMException;
|
||||
@ -484,8 +504,10 @@ module.exports = {
|
||||
createClassWrapper,
|
||||
createDeferredPromise,
|
||||
decorateErrorStack,
|
||||
defineOperation,
|
||||
deprecate,
|
||||
emitExperimentalWarning,
|
||||
exposeInterface,
|
||||
filterDuplicateStrings,
|
||||
getConstructorOf,
|
||||
getSystemErrorMap,
|
||||
|
@ -882,6 +882,15 @@ inline bool Environment::no_global_search_paths() const {
|
||||
!options_->global_search_paths;
|
||||
}
|
||||
|
||||
inline bool Environment::no_browser_globals() const {
|
||||
// configure --no-browser-globals
|
||||
#ifdef NODE_NO_BROWSER_GLOBALS
|
||||
return true;
|
||||
#else
|
||||
return flags_ & EnvironmentFlags::kNoBrowserGlobals;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Environment::filehandle_close_warning() const {
|
||||
return emit_filehandle_warning_;
|
||||
}
|
||||
|
@ -1212,6 +1212,7 @@ class Environment : public MemoryRetainer {
|
||||
inline bool tracks_unmanaged_fds() const;
|
||||
inline bool hide_console_windows() const;
|
||||
inline bool no_global_search_paths() const;
|
||||
inline bool no_browser_globals() const;
|
||||
inline uint64_t thread_id() const;
|
||||
inline worker::Worker* worker_context() const;
|
||||
Environment* worker_parent_env() const;
|
||||
|
15
src/node.cc
15
src/node.cc
@ -360,7 +360,16 @@ MaybeLocal<Value> Environment::BootstrapNode() {
|
||||
this, "internal/bootstrap/node", &node_params, &node_args);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return scope.EscapeMaybe(result);
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
if (!no_browser_globals()) {
|
||||
result = ExecuteBootstrapper(
|
||||
this, "internal/bootstrap/browser", &node_params, &node_args);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(joyeecheung): skip these in the snapshot building for workers.
|
||||
@ -371,7 +380,7 @@ MaybeLocal<Value> Environment::BootstrapNode() {
|
||||
ExecuteBootstrapper(this, thread_switch_id, &node_params, &node_args);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return scope.EscapeMaybe(result);
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
auto process_state_switch_id =
|
||||
@ -382,7 +391,7 @@ MaybeLocal<Value> Environment::BootstrapNode() {
|
||||
this, process_state_switch_id, &node_params, &node_args);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return scope.EscapeMaybe(result);
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
Local<String> env_string = FIXED_ONE_BYTE_STRING(isolate_, "env");
|
||||
|
@ -439,7 +439,9 @@ enum Flags : uint64_t {
|
||||
// $HOME/.node_modules and $NODE_PATH. This is used by standalone apps that
|
||||
// do not expect to have their behaviors changed because of globally
|
||||
// installed modules.
|
||||
kNoGlobalSearchPaths = 1 << 7
|
||||
kNoGlobalSearchPaths = 1 << 7,
|
||||
// Do not export browser globals like setTimeout, console, etc.
|
||||
kNoBrowserGlobals = 1 << 8,
|
||||
};
|
||||
} // namespace EnvironmentFlags
|
||||
|
||||
|
@ -574,6 +574,8 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) {
|
||||
worker->environment_flags_ |= EnvironmentFlags::kNoNativeAddons;
|
||||
if (env->no_global_search_paths())
|
||||
worker->environment_flags_ |= EnvironmentFlags::kNoGlobalSearchPaths;
|
||||
if (env->no_browser_globals())
|
||||
worker->environment_flags_ |= EnvironmentFlags::kNoBrowserGlobals;
|
||||
}
|
||||
|
||||
void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user