From 0acb361cffa3a09f709a7f4e69d8fc6a7ac18e80 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 24 Apr 2024 20:57:29 -0700 Subject: [PATCH] lib: make navigator not runtime-lookup process.version/arch/platform Preserves most of #53649, except for `#language` due to the lack of Intl primordials. --- lib/internal/bootstrap/node.js | 4 ++ lib/internal/navigator.js | 46 +++++++++--------- lib/internal/process/arch.js | 3 ++ lib/internal/process/platform.js | 3 ++ lib/internal/process/version.js | 3 ++ test/parallel/test-bootstrap-modules.js | 32 +++++++------ test/parallel/test-navigator.js | 64 ++++++++++++++++++------- 7 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 lib/internal/process/arch.js create mode 100644 lib/internal/process/platform.js create mode 100644 lib/internal/process/version.js diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index d634b0405dbadd..4bf9270c7f1d3e 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -85,6 +85,10 @@ const { }, } = internalBinding('util'); +require('internal/process/arch'); // Ensure the process arch is cached +require('internal/process/platform'); // Ensure the process platform is cached +require('internal/process/version'); // Etnsure the process version is cached + setupProcessObject(); setupGlobalProxy(); diff --git a/lib/internal/navigator.js b/lib/internal/navigator.js index e56b2da5e339e3..c3da23a5c7a540 100644 --- a/lib/internal/navigator.js +++ b/lib/internal/navigator.js @@ -27,7 +27,9 @@ const { } = internalBinding('os'); const kInitialize = Symbol('kInitialize'); -const nodeVersion = process.version; +const nodeVersion = require('internal/process/version'); +const platform = require('internal/process/platform'); +const arch = require('internal/process/arch'); /** * @param {object} process @@ -35,44 +37,44 @@ const nodeVersion = process.version; * @param {string} process.arch * @returns {string} */ -function getNavigatorPlatform(process) { - if (process.platform === 'darwin') { +function getNavigatorPlatform(arch, platform) { + if (platform === 'darwin') { // On macOS, modern browsers return 'MacIntel' even if running on Apple Silicon. return 'MacIntel'; - } else if (process.platform === 'win32') { + } else if (platform === 'win32') { // On Windows, modern browsers return 'Win32' even if running on a 64-bit version of Windows. // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#usage_notes return 'Win32'; - } else if (process.platform === 'linux') { - if (process.arch === 'ia32') { + } else if (platform === 'linux') { + if (arch === 'ia32') { return 'Linux i686'; - } else if (process.arch === 'x64') { + } else if (arch === 'x64') { return 'Linux x86_64'; } - return `Linux ${process.arch}`; - } else if (process.platform === 'freebsd') { - if (process.arch === 'ia32') { + return `Linux ${arch}`; + } else if (platform === 'freebsd') { + if (arch === 'ia32') { return 'FreeBSD i386'; - } else if (process.arch === 'x64') { + } else if (arch === 'x64') { return 'FreeBSD amd64'; } - return `FreeBSD ${process.arch}`; - } else if (process.platform === 'openbsd') { - if (process.arch === 'ia32') { + return `FreeBSD ${arch}`; + } else if (platform === 'openbsd') { + if (arch === 'ia32') { return 'OpenBSD i386'; - } else if (process.arch === 'x64') { + } else if (arch === 'x64') { return 'OpenBSD amd64'; } - return `OpenBSD ${process.arch}`; - } else if (process.platform === 'sunos') { - if (process.arch === 'ia32') { + return `OpenBSD ${arch}`; + } else if (platform === 'sunos') { + if (arch === 'ia32') { return 'SunOS i86pc'; } - return `SunOS ${process.arch}`; - } else if (process.platform === 'aix') { + return `SunOS ${arch}`; + } else if (platform === 'aix') { return 'AIX'; } - return `${StringPrototypeToUpperCase(process.platform[0])}${StringPrototypeSlice(process.platform, 1)} ${process.arch}`; + return `${StringPrototypeToUpperCase(platform[0])}${StringPrototypeSlice(platform, 1)} ${arch}`; } class Navigator { @@ -126,7 +128,7 @@ class Navigator { * @return {string} */ get platform() { - this.#platform ??= getNavigatorPlatform(process); + this.#platform ??= getNavigatorPlatform(arch, platform); return this.#platform; } } diff --git a/lib/internal/process/arch.js b/lib/internal/process/arch.js new file mode 100644 index 00000000000000..c85822d0118a1b --- /dev/null +++ b/lib/internal/process/arch.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('process').arch; diff --git a/lib/internal/process/platform.js b/lib/internal/process/platform.js new file mode 100644 index 00000000000000..32ce9a172a4971 --- /dev/null +++ b/lib/internal/process/platform.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('process').platform; diff --git a/lib/internal/process/version.js b/lib/internal/process/version.js new file mode 100644 index 00000000000000..138753faab1533 --- /dev/null +++ b/lib/internal/process/version.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('process').version; diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index 71e2854f8e2d47..882f7919025faf 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -58,28 +58,32 @@ expected.beforePreExec = new Set([ 'NativeModule internal/process/promises', 'NativeModule internal/fixed_queue', 'NativeModule async_hooks', - 'NativeModule internal/process/task_queues', - 'NativeModule timers', + 'Internal Binding blob', + 'Internal Binding mksnapshot', + 'Internal Binding performance', + 'Internal Binding permission', 'Internal Binding trace_events', + 'Internal Binding url', + 'NativeModule internal/console/constructor', + 'NativeModule internal/console/global', 'NativeModule internal/constants', - 'NativeModule path', + 'NativeModule internal/event_target', + 'NativeModule internal/perf/utils', + 'NativeModule internal/process/arch', 'NativeModule internal/process/execution', 'NativeModule internal/process/permission', + 'NativeModule internal/process/platform', + 'NativeModule internal/process/task_queues', + 'NativeModule internal/process/version', 'NativeModule internal/process/warning', - 'NativeModule internal/console/constructor', - 'NativeModule internal/console/global', 'NativeModule internal/querystring', - 'NativeModule querystring', - 'Internal Binding url', - 'Internal Binding blob', 'NativeModule internal/url', - 'NativeModule util', 'NativeModule internal/webidl', - 'Internal Binding performance', - 'Internal Binding permission', - 'NativeModule internal/perf/utils', - 'NativeModule internal/event_target', - 'Internal Binding mksnapshot', + 'NativeModule path', + 'NativeModule process', + 'NativeModule querystring', + 'NativeModule timers', + 'NativeModule util', 'NativeModule internal/v8/startup_snapshot', 'NativeModule internal/process/signal', 'Internal Binding fs', diff --git a/test/parallel/test-navigator.js b/test/parallel/test-navigator.js index 53949cea246d16..ebd1f67760bd44 100644 --- a/test/parallel/test-navigator.js +++ b/test/parallel/test-navigator.js @@ -2,8 +2,36 @@ 'use strict'; -const common = require('../common'); +/* eslint node-core/require-common-first: 0 */ + const assert = require('assert'); + +{ + + // Ensures `navigator` has not been evaluated yet + assert.strictEqual(require.resolve('../common') in require.cache, false); + + const { version, platform, arch } = process; + try { + let called = false; + Object.defineProperty(process, 'arch', { get() { called += 'arch|'; return arch; } }); + Object.defineProperty(process, 'platform', { get() { called = 'platform|'; return platform; } }); + Object.defineProperty(process, 'version', { get() { called = 'version|'; return version; } }); + + navigator; // eslint-disable-line no-unused-expressions + + assert.strictEqual( + called, + false + ); + } finally { + Object.defineProperty(process, 'arch', { value: arch }); + Object.defineProperty(process, 'platform', { value: platform }); + Object.defineProperty(process, 'version', { value: version }); + } +} + +const common = require('../common'); const { getNavigatorPlatform } = require('internal/navigator'); const { execFile } = require('child_process'); @@ -57,23 +85,23 @@ if (process.platform === 'darwin') { assert.strictEqual(navigator.platform, `${process.platform[0].toUpperCase()}${process.platform.slice(1)} ${process.arch}`); } -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'darwin' }), 'MacIntel'); -assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'darwin' }), 'MacIntel'); -assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'linux' }), 'Linux i686'); -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'linux' }), 'Linux x86_64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'linux' }), 'Linux arm64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'win32' }), 'Win32'); -assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'win32' }), 'Win32'); -assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'freebsd' }), 'FreeBSD i386'); -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'freebsd' }), 'FreeBSD amd64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'freebsd' }), 'FreeBSD arm64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'openbsd' }), 'OpenBSD i386'); -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'openbsd' }), 'OpenBSD amd64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'openbsd' }), 'OpenBSD arm64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'sunos' }), 'SunOS i86pc'); -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'sunos' }), 'SunOS x64'); -assert.strictEqual(getNavigatorPlatform({ arch: 'ppc', platform: 'aix' }), 'AIX'); -assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'reactos' }), 'Reactos x64'); +assert.strictEqual(getNavigatorPlatform('x64', 'darwin'), 'MacIntel'); +assert.strictEqual(getNavigatorPlatform('arm64', 'darwin'), 'MacIntel'); +assert.strictEqual(getNavigatorPlatform('ia32', 'linux'), 'Linux i686'); +assert.strictEqual(getNavigatorPlatform('x64', 'linux'), 'Linux x86_64'); +assert.strictEqual(getNavigatorPlatform('arm64', 'linux'), 'Linux arm64'); +assert.strictEqual(getNavigatorPlatform('x64', 'win32'), 'Win32'); +assert.strictEqual(getNavigatorPlatform('arm64', 'win32'), 'Win32'); +assert.strictEqual(getNavigatorPlatform('ia32', 'freebsd'), 'FreeBSD i386'); +assert.strictEqual(getNavigatorPlatform('x64', 'freebsd'), 'FreeBSD amd64'); +assert.strictEqual(getNavigatorPlatform('arm64', 'freebsd'), 'FreeBSD arm64'); +assert.strictEqual(getNavigatorPlatform('ia32', 'openbsd'), 'OpenBSD i386'); +assert.strictEqual(getNavigatorPlatform('x64', 'openbsd'), 'OpenBSD amd64'); +assert.strictEqual(getNavigatorPlatform('arm64', 'openbsd'), 'OpenBSD arm64'); +assert.strictEqual(getNavigatorPlatform('ia32', 'sunos'), 'SunOS i86pc'); +assert.strictEqual(getNavigatorPlatform('x64', 'sunos'), 'SunOS x64'); +assert.strictEqual(getNavigatorPlatform('ppc', 'aix'), 'AIX'); +assert.strictEqual(getNavigatorPlatform('x64', 'reactos'), 'Reactos x64'); assert.strictEqual(typeof navigator.language, 'string'); assert.strictEqual(navigator.language.length !== 0, true);