From d4f96bb926325268ad231ff99c8ffcc9ff6ada09 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 13 Apr 2021 18:54:09 +0200 Subject: [PATCH] lib: enforce using `primordials.globalThis` instead of `global` PR-URL: /~https://github.com/nodejs/node/pull/38230 Backport-PR-URL: /~https://github.com/nodejs/node/pull/39448 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Darshan Sen Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca --- lib/.eslintrc.yaml | 2 ++ lib/internal/bootstrap/node.js | 32 +++++++++++++------------ lib/internal/bootstrap/pre_execution.js | 7 +++--- lib/internal/main/eval_string.js | 6 ++++- lib/internal/per_context/primordials.js | 3 +++ lib/internal/util/inspect.js | 11 +++++++-- lib/repl.js | 10 ++++---- 7 files changed, 46 insertions(+), 25 deletions(-) diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index 626bac70930703..0e6f84dc14754f 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -29,6 +29,8 @@ rules: - error - name: globalThis message: "Use `const { globalThis } = primordials;` instead of the global." + - name: global + message: "Use `const { globalThis } = primordials;` instead of `global`." # Custom rules in tools/eslint-rules node-core/lowercase-name-for-primitive: error node-core/non-ascii-character: error diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 2705f8b50a658d..718c9a6ac6491e 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -45,6 +45,7 @@ const { ObjectGetPrototypeOf, ObjectSetPrototypeOf, SymbolToStringTag, + globalThis, } = primordials; const config = internalBinding('config'); const { deprecate } = require('internal/util'); @@ -119,34 +120,35 @@ 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(global, 'console', createGlobalConsole(global.console)); + exposeNamespace(globalThis, 'console', + createGlobalConsole(globalThis.console)); const { URL, URLSearchParams } = require('internal/url'); // https://url.spec.whatwg.org/#url - exposeInterface(global, 'URL', URL); + exposeInterface(globalThis, 'URL', URL); // https://url.spec.whatwg.org/#urlsearchparams - exposeInterface(global, 'URLSearchParams', URLSearchParams); + exposeInterface(globalThis, 'URLSearchParams', URLSearchParams); const { TextEncoder, TextDecoder } = require('internal/encoding'); // https://encoding.spec.whatwg.org/#textencoder - exposeInterface(global, 'TextEncoder', TextEncoder); + exposeInterface(globalThis, 'TextEncoder', TextEncoder); // https://encoding.spec.whatwg.org/#textdecoder - exposeInterface(global, 'TextDecoder', TextDecoder); + exposeInterface(globalThis, 'TextDecoder', TextDecoder); // https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope const timers = require('timers'); - defineOperation(global, 'clearInterval', timers.clearInterval); - defineOperation(global, 'clearTimeout', timers.clearTimeout); - defineOperation(global, 'setInterval', timers.setInterval); - defineOperation(global, 'setTimeout', timers.setTimeout); + defineOperation(globalThis, 'clearInterval', timers.clearInterval); + defineOperation(globalThis, 'clearTimeout', timers.clearTimeout); + defineOperation(globalThis, 'setInterval', timers.setInterval); + defineOperation(globalThis, 'setTimeout', timers.setTimeout); - defineOperation(global, 'queueMicrotask', queueMicrotask); + defineOperation(globalThis, 'queueMicrotask', queueMicrotask); // Non-standard extensions: - defineOperation(global, 'clearImmediate', timers.clearImmediate); - defineOperation(global, 'setImmediate', timers.setImmediate); + defineOperation(globalThis, 'clearImmediate', timers.clearImmediate); + defineOperation(globalThis, 'setImmediate', timers.setImmediate); } // Set the per-Environment callback that will be called @@ -280,7 +282,7 @@ function setupProcessObject() { value: 'process' }); // Make process globally available to users by putting it on the global proxy - ObjectDefineProperty(global, 'process', { + ObjectDefineProperty(globalThis, 'process', { value: process, enumerable: false, writable: true, @@ -289,7 +291,7 @@ function setupProcessObject() { } function setupGlobalProxy() { - ObjectDefineProperty(global, SymbolToStringTag, { + ObjectDefineProperty(globalThis, SymbolToStringTag, { value: 'global', writable: false, enumerable: false, @@ -306,7 +308,7 @@ function setupBuffer() { delete bufferBinding.setBufferPrototype; delete bufferBinding.zeroFill; - ObjectDefineProperty(global, 'Buffer', { + ObjectDefineProperty(globalThis, 'Buffer', { value: Buffer, enumerable: false, writable: true, diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index dfd7249e907ebc..61f3aea190fd4c 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -7,6 +7,7 @@ const { SafeMap, SafeWeakMap, StringPrototypeStartsWith, + globalThis, } = primordials; const { @@ -290,7 +291,7 @@ function initializeDeprecations() { // deprecation path for these in ES Modules. // See /~https://github.com/nodejs/node/pull/26334. let _process = process; - ObjectDefineProperty(global, 'process', { + ObjectDefineProperty(globalThis, 'process', { get() { return _process; }, @@ -302,7 +303,7 @@ function initializeDeprecations() { }); let _Buffer = Buffer; - ObjectDefineProperty(global, 'Buffer', { + ObjectDefineProperty(globalThis, 'Buffer', { get() { return _Buffer; }, @@ -321,7 +322,7 @@ function initializeAbortController() { AbortController, AbortSignal } = require('internal/abort_controller'); - ObjectDefineProperties(global, { + ObjectDefineProperties(globalThis, { AbortController: { writable: true, enumerable: false, diff --git a/lib/internal/main/eval_string.js b/lib/internal/main/eval_string.js index 124e4842308c55..ad068b935dfee0 100644 --- a/lib/internal/main/eval_string.js +++ b/lib/internal/main/eval_string.js @@ -3,6 +3,10 @@ // User passed `-e` or `--eval` arguments to Node without `-i` or // `--interactive`. +const { + globalThis, +} = primordials; + const { prepareMainThreadExecution } = require('internal/bootstrap/pre_execution'); @@ -12,7 +16,7 @@ const { addBuiltinLibsToObject } = require('internal/modules/cjs/helpers'); const { getOptionValue } = require('internal/options'); prepareMainThreadExecution(); -addBuiltinLibsToObject(global); +addBuiltinLibsToObject(globalThis); markBootstrapComplete(); const source = getOptionValue('--eval'); diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 595be166546e1b..c80f22be331109 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -195,6 +195,7 @@ primordials.SafeWeakSet = makeSafe( 'Math', 'Reflect' ].forEach((name) => { + // eslint-disable-next-line no-restricted-globals copyPropsRenamed(global[name], primordials, name); }); @@ -235,6 +236,7 @@ primordials.SafeWeakSet = makeSafe( 'WeakMap', 'WeakSet', ].forEach((name) => { + // eslint-disable-next-line no-restricted-globals const original = global[name]; primordials[name] = original; copyPropsRenamed(original, primordials, name); @@ -247,6 +249,7 @@ primordials.SafeWeakSet = makeSafe( [ 'Promise', ].forEach((name) => { + // eslint-disable-next-line no-restricted-globals const original = global[name]; primordials[name] = original; copyPropsRenamedBound(original, primordials, name); diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 14b4e54e4f4157..e8728370cd1e6c 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -3,6 +3,7 @@ const { Array, ArrayIsArray, + ArrayPrototypeFilter, BigIntPrototypeValueOf, BooleanPrototypeValueOf, DatePrototypeGetTime, @@ -41,7 +42,9 @@ const { ObjectSetPrototypeOf, ReflectApply, RegExp, + RegExpPrototypeExec, RegExpPrototypeToString, + SafeSet, SafeStringIterator, Set, SetPrototypeGetSize, @@ -55,6 +58,7 @@ const { TypedArrayPrototypeGetLength, TypedArrayPrototypeGetSymbolToStringTag, Uint8Array, + globalThis, uncurryThis, } = primordials; @@ -120,8 +124,11 @@ const { NativeModule } = require('internal/bootstrap/loaders'); let hexSlice; -const builtInObjects = new Set( - ObjectGetOwnPropertyNames(global).filter((e) => /^[A-Z][a-zA-Z0-9]+$/.test(e)) +const builtInObjects = new SafeSet( + ArrayPrototypeFilter( + ObjectGetOwnPropertyNames(globalThis), + (e) => RegExpPrototypeExec(/^[A-Z][a-zA-Z0-9]+$/, e) !== null + ) ); // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot diff --git a/lib/repl.js b/lib/repl.js index 1ec438e5210e49..cfcbf126ee8cf0 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -43,6 +43,7 @@ 'use strict'; const { + ArrayPrototypeForEach, Error, MathMax, NumberIsNaN, @@ -67,6 +68,7 @@ const { SyntaxError, SyntaxErrorPrototype, WeakSet, + globalThis, } = primordials; const { @@ -984,7 +986,7 @@ REPLServer.prototype.close = function close() { REPLServer.prototype.createContext = function() { let context; if (this.useGlobal) { - context = global; + context = globalThis; } else { sendInspectorCommand((session) => { session.post('Runtime.enable'); @@ -996,13 +998,13 @@ REPLServer.prototype.createContext = function() { }, () => { context = vm.createContext(); }); - for (const name of ObjectGetOwnPropertyNames(global)) { + ArrayPrototypeForEach(ObjectGetOwnPropertyNames(globalThis), (name) => { // Only set properties that do not already exist as a global builtin. if (!globalBuiltins.has(name)) { ObjectDefineProperty(context, name, - ObjectGetOwnPropertyDescriptor(global, name)); + ObjectGetOwnPropertyDescriptor(globalThis, name)); } - } + }); context.global = context; const _console = new Console(this.output); ObjectDefineProperty(context, 'console', {