Skip to content

Commit 8278b99

Browse files
committed
src: add kNoBrowserGlobals flag for Environment
1 parent c0a7020 commit 8278b99

File tree

8 files changed

+174
-145
lines changed

8 files changed

+174
-145
lines changed

configure.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,8 @@
703703
dest='no_browser_globals',
704704
default=None,
705705
help='do not export browser globals like setTimeout, console, etc. ' +
706-
'(This mode is not officially supported for regular applications)')
706+
'(This mode is deprecated and not officially supported for regular ' +
707+
'applications)')
707708

708709
parser.add_argument('--without-inspector',
709710
action='store_true',

lib/internal/bootstrap/browser.js

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
'use strict';
2+
3+
const {
4+
ObjectDefineProperty,
5+
globalThis,
6+
} = primordials;
7+
8+
const { lazyDOMExceptionClass } = require('internal/util');
9+
const config = internalBinding('config');
10+
11+
// Override global console from the one provided by the VM
12+
// to the one implemented by Node.js
13+
// https://console.spec.whatwg.org/#console-namespace
14+
exposeNamespace(globalThis, 'console',
15+
createGlobalConsole(globalThis.console));
16+
17+
const { URL, URLSearchParams } = require('internal/url');
18+
// https://url.spec.whatwg.org/#url
19+
exposeInterface(globalThis, 'URL', URL);
20+
// https://url.spec.whatwg.org/#urlsearchparams
21+
exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
22+
exposeGetterAndSetter(globalThis,
23+
'DOMException',
24+
lazyDOMExceptionClass,
25+
(value) => {
26+
exposeInterface(globalThis, 'DOMException', value);
27+
});
28+
29+
const {
30+
TextEncoder, TextDecoder
31+
} = require('internal/encoding');
32+
// https://encoding.spec.whatwg.org/#textencoder
33+
exposeInterface(globalThis, 'TextEncoder', TextEncoder);
34+
// https://encoding.spec.whatwg.org/#textdecoder
35+
exposeInterface(globalThis, 'TextDecoder', TextDecoder);
36+
37+
const {
38+
AbortController,
39+
AbortSignal,
40+
} = require('internal/abort_controller');
41+
exposeInterface(globalThis, 'AbortController', AbortController);
42+
exposeInterface(globalThis, 'AbortSignal', AbortSignal);
43+
44+
const {
45+
EventTarget,
46+
Event,
47+
} = require('internal/event_target');
48+
exposeInterface(globalThis, 'EventTarget', EventTarget);
49+
exposeInterface(globalThis, 'Event', Event);
50+
const {
51+
MessageChannel,
52+
MessagePort,
53+
MessageEvent,
54+
} = require('internal/worker/io');
55+
exposeInterface(globalThis, 'MessageChannel', MessageChannel);
56+
exposeInterface(globalThis, 'MessagePort', MessagePort);
57+
exposeInterface(globalThis, 'MessageEvent', MessageEvent);
58+
59+
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
60+
const timers = require('timers');
61+
defineOperation(globalThis, 'clearInterval', timers.clearInterval);
62+
defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
63+
defineOperation(globalThis, 'setInterval', timers.setInterval);
64+
defineOperation(globalThis, 'setTimeout', timers.setTimeout);
65+
66+
const { queueMicrotask } = require('internal/process/task_queues');
67+
defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
68+
69+
// https://www.w3.org/TR/hr-time-2/#the-performance-attribute
70+
defineReplacableAttribute(globalThis, 'performance',
71+
require('perf_hooks').performance);
72+
73+
// Non-standard extensions:
74+
defineOperation(globalThis, 'clearImmediate', timers.clearImmediate);
75+
defineOperation(globalThis, 'setImmediate', timers.setImmediate);
76+
77+
const {
78+
structuredClone,
79+
} = require('internal/structured_clone');
80+
defineOperation(globalThis, 'structuredClone', structuredClone);
81+
82+
function createGlobalConsole(consoleFromVM) {
83+
const consoleFromNode =
84+
require('internal/console/global');
85+
if (config.hasInspector) {
86+
const inspector = require('internal/util/inspector');
87+
// This will be exposed by `require('inspector').console` later.
88+
inspector.consoleFromVM = consoleFromVM;
89+
// TODO(joyeecheung): postpone this until the first time inspector
90+
// is activated.
91+
inspector.wrapConsole(consoleFromNode, consoleFromVM);
92+
const { setConsoleExtensionInstaller } = internalBinding('inspector');
93+
// Setup inspector command line API.
94+
setConsoleExtensionInstaller(inspector.installConsoleExtensions);
95+
}
96+
return consoleFromNode;
97+
}
98+
99+
// https://heycam.github.io/webidl/#es-namespaces
100+
function exposeNamespace(target, name, namespaceObject) {
101+
ObjectDefineProperty(target, name, {
102+
writable: true,
103+
enumerable: false,
104+
configurable: true,
105+
value: namespaceObject
106+
});
107+
}
108+
109+
// https://heycam.github.io/webidl/#es-interfaces
110+
function exposeInterface(target, name, interfaceObject) {
111+
ObjectDefineProperty(target, name, {
112+
writable: true,
113+
enumerable: false,
114+
configurable: true,
115+
value: interfaceObject
116+
});
117+
}
118+
119+
function exposeGetterAndSetter(target, name, getter, setter = undefined) {
120+
ObjectDefineProperty(target, name, {
121+
enumerable: false,
122+
configurable: true,
123+
get: getter,
124+
set: setter,
125+
});
126+
}
127+
128+
// https://heycam.github.io/webidl/#define-the-operations
129+
function defineOperation(target, name, method) {
130+
ObjectDefineProperty(target, name, {
131+
writable: true,
132+
enumerable: true,
133+
configurable: true,
134+
value: method
135+
});
136+
}
137+
138+
// https://heycam.github.io/webidl/#Replaceable
139+
function defineReplacableAttribute(target, name, value) {
140+
ObjectDefineProperty(target, name, {
141+
writable: true,
142+
enumerable: true,
143+
configurable: true,
144+
value,
145+
});
146+
}

lib/internal/bootstrap/node.js

+2-143
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const {
5252
globalThis,
5353
} = primordials;
5454
const config = internalBinding('config');
55-
const { deprecate, lazyDOMExceptionClass } = require('internal/util');
55+
const { deprecate } = require('internal/util');
5656

5757
setupProcessObject();
5858

@@ -184,82 +184,7 @@ if (credentials.implementsPosixCredentials) {
184184
const { nativeHooks } = require('internal/async_hooks');
185185
internalBinding('async_wrap').setupHooks(nativeHooks);
186186

187-
const {
188-
setupTaskQueue,
189-
queueMicrotask
190-
} = require('internal/process/task_queues');
191-
192-
if (!config.noBrowserGlobals) {
193-
// Override global console from the one provided by the VM
194-
// to the one implemented by Node.js
195-
// https://console.spec.whatwg.org/#console-namespace
196-
exposeNamespace(globalThis, 'console',
197-
createGlobalConsole(globalThis.console));
198-
199-
const { URL, URLSearchParams } = require('internal/url');
200-
// https://url.spec.whatwg.org/#url
201-
exposeInterface(globalThis, 'URL', URL);
202-
// https://url.spec.whatwg.org/#urlsearchparams
203-
exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
204-
exposeGetterAndSetter(globalThis,
205-
'DOMException',
206-
lazyDOMExceptionClass,
207-
(value) => {
208-
exposeInterface(globalThis, 'DOMException', value);
209-
});
210-
211-
const {
212-
TextEncoder, TextDecoder
213-
} = require('internal/encoding');
214-
// https://encoding.spec.whatwg.org/#textencoder
215-
exposeInterface(globalThis, 'TextEncoder', TextEncoder);
216-
// https://encoding.spec.whatwg.org/#textdecoder
217-
exposeInterface(globalThis, 'TextDecoder', TextDecoder);
218-
219-
const {
220-
AbortController,
221-
AbortSignal,
222-
} = require('internal/abort_controller');
223-
exposeInterface(globalThis, 'AbortController', AbortController);
224-
exposeInterface(globalThis, 'AbortSignal', AbortSignal);
225-
226-
const {
227-
EventTarget,
228-
Event,
229-
} = require('internal/event_target');
230-
exposeInterface(globalThis, 'EventTarget', EventTarget);
231-
exposeInterface(globalThis, 'Event', Event);
232-
const {
233-
MessageChannel,
234-
MessagePort,
235-
MessageEvent,
236-
} = require('internal/worker/io');
237-
exposeInterface(globalThis, 'MessageChannel', MessageChannel);
238-
exposeInterface(globalThis, 'MessagePort', MessagePort);
239-
exposeInterface(globalThis, 'MessageEvent', MessageEvent);
240-
241-
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
242-
const timers = require('timers');
243-
defineOperation(globalThis, 'clearInterval', timers.clearInterval);
244-
defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
245-
defineOperation(globalThis, 'setInterval', timers.setInterval);
246-
defineOperation(globalThis, 'setTimeout', timers.setTimeout);
247-
248-
defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
249-
250-
// https://www.w3.org/TR/hr-time-2/#the-performance-attribute
251-
defineReplacableAttribute(globalThis, 'performance',
252-
require('perf_hooks').performance);
253-
254-
// Non-standard extensions:
255-
defineOperation(globalThis, 'clearImmediate', timers.clearImmediate);
256-
defineOperation(globalThis, 'setImmediate', timers.setImmediate);
257-
258-
const {
259-
structuredClone,
260-
} = require('internal/structured_clone');
261-
defineOperation(globalThis, 'structuredClone', structuredClone);
262-
}
187+
const { setupTaskQueue } = require('internal/process/task_queues');
263188

264189
// Set the per-Environment callback that will be called
265190
// when the TrackingTraceStateObserver updates trace state.
@@ -456,69 +381,3 @@ function setupBuffer() {
456381
},
457382
});
458383
}
459-
460-
function createGlobalConsole(consoleFromVM) {
461-
const consoleFromNode =
462-
require('internal/console/global');
463-
if (config.hasInspector) {
464-
const inspector = require('internal/util/inspector');
465-
// This will be exposed by `require('inspector').console` later.
466-
inspector.consoleFromVM = consoleFromVM;
467-
// TODO(joyeecheung): postpone this until the first time inspector
468-
// is activated.
469-
inspector.wrapConsole(consoleFromNode, consoleFromVM);
470-
const { setConsoleExtensionInstaller } = internalBinding('inspector');
471-
// Setup inspector command line API.
472-
setConsoleExtensionInstaller(inspector.installConsoleExtensions);
473-
}
474-
return consoleFromNode;
475-
}
476-
477-
// https://heycam.github.io/webidl/#es-namespaces
478-
function exposeNamespace(target, name, namespaceObject) {
479-
ObjectDefineProperty(target, name, {
480-
writable: true,
481-
enumerable: false,
482-
configurable: true,
483-
value: namespaceObject
484-
});
485-
}
486-
487-
// https://heycam.github.io/webidl/#es-interfaces
488-
function exposeInterface(target, name, interfaceObject) {
489-
ObjectDefineProperty(target, name, {
490-
writable: true,
491-
enumerable: false,
492-
configurable: true,
493-
value: interfaceObject
494-
});
495-
}
496-
497-
function exposeGetterAndSetter(target, name, getter, setter = undefined) {
498-
ObjectDefineProperty(target, name, {
499-
enumerable: false,
500-
configurable: true,
501-
get: getter,
502-
set: setter,
503-
});
504-
}
505-
506-
// https://heycam.github.io/webidl/#define-the-operations
507-
function defineOperation(target, name, method) {
508-
ObjectDefineProperty(target, name, {
509-
writable: true,
510-
enumerable: true,
511-
configurable: true,
512-
value: method
513-
});
514-
}
515-
516-
// https://heycam.github.io/webidl/#Replaceable
517-
function defineReplacableAttribute(target, name, value) {
518-
ObjectDefineProperty(target, name, {
519-
writable: true,
520-
enumerable: true,
521-
configurable: true,
522-
value,
523-
});
524-
}

src/env-inl.h

+9
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,15 @@ inline bool Environment::no_global_search_paths() const {
892892
!options_->global_search_paths;
893893
}
894894

895+
inline bool Environment::no_browser_globals() const {
896+
// configure --no-browser-globals
897+
#ifdef NODE_NO_BROWSER_GLOBALS
898+
return true;
899+
#else
900+
return flags_ & EnvironmentFlags::kNoBrowserGlobals;
901+
#endif
902+
}
903+
895904
bool Environment::filehandle_close_warning() const {
896905
return emit_filehandle_warning_;
897906
}

src/env.h

+1
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ class Environment : public MemoryRetainer {
12041204
inline bool tracks_unmanaged_fds() const;
12051205
inline bool hide_console_windows() const;
12061206
inline bool no_global_search_paths() const;
1207+
inline bool no_browser_globals() const;
12071208
inline uint64_t thread_id() const;
12081209
inline worker::Worker* worker_context() const;
12091210
Environment* worker_parent_env() const;

src/node.cc

+9
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,15 @@ MaybeLocal<Value> Environment::BootstrapNode() {
363363
return scope.EscapeMaybe(result);
364364
}
365365

366+
if (!no_browser_globals()) {
367+
result = ExecuteBootstrapper(
368+
this, "internal/bootstrap/browser", &node_params, &node_args);
369+
370+
if (result.IsEmpty()) {
371+
return scope.EscapeMaybe(result);
372+
}
373+
}
374+
366375
// TODO(joyeecheung): skip these in the snapshot building for workers.
367376
auto thread_switch_id =
368377
is_main_thread() ? "internal/bootstrap/switches/is_main_thread"

src/node.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,9 @@ enum Flags : uint64_t {
439439
// $HOME/.node_modules and $NODE_PATH. This is used by standalone apps that
440440
// do not expect to have their behaviors changed because of globally
441441
// installed modules.
442-
kNoGlobalSearchPaths = 1 << 7
442+
kNoGlobalSearchPaths = 1 << 7,
443+
// Do not export browser globals like setTimeout, console, etc.
444+
kNoBrowserGlobals = 1 << 8,
443445
};
444446
} // namespace EnvironmentFlags
445447

src/node_worker.cc

+2
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,8 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) {
574574
worker->environment_flags_ |= EnvironmentFlags::kNoNativeAddons;
575575
if (env->no_global_search_paths())
576576
worker->environment_flags_ |= EnvironmentFlags::kNoGlobalSearchPaths;
577+
if (env->no_browser_globals())
578+
worker->environment_flags_ |= EnvironmentFlags::kNoBrowserGlobals;
577579
}
578580

579581
void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {

0 commit comments

Comments
 (0)