Skip to content

Commit 42edb23

Browse files
committed
lib: make navigator not runtime-lookup process.version/arch/platform
Preserves #53649.
1 parent cff7da7 commit 42edb23

File tree

5 files changed

+97
-53
lines changed

5 files changed

+97
-53
lines changed

lib/internal/navigator.js

+34-33
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,8 @@ const {
77
StringPrototypeSlice,
88
StringPrototypeToUpperCase,
99
Symbol,
10-
globalThis,
1110
} = primordials;
1211

13-
const {
14-
Intl,
15-
} = globalThis;
16-
1712
const {
1813
ERR_ILLEGAL_CONSTRUCTOR,
1914
} = require('internal/errors').codes;
@@ -27,60 +22,67 @@ const {
2722
} = internalBinding('os');
2823

2924
const kInitialize = Symbol('kInitialize');
30-
const nodeVersion = process.version;
25+
26+
const {
27+
platform,
28+
arch,
29+
version: nodeVersion,
30+
} = require('internal/process/per_thread');
31+
32+
const {
33+
language,
34+
} = internalBinding('config');
3135

3236
/**
33-
* @param {object} process
34-
* @param {string} process.platform
35-
* @param {string} process.arch
37+
* @param {string} arch
38+
* @param {string} platform
3639
* @returns {string}
3740
*/
38-
function getNavigatorPlatform(process) {
39-
if (process.platform === 'darwin') {
41+
function getNavigatorPlatform(arch, platform) {
42+
if (platform === 'darwin') {
4043
// On macOS, modern browsers return 'MacIntel' even if running on Apple Silicon.
4144
return 'MacIntel';
42-
} else if (process.platform === 'win32') {
45+
} else if (platform === 'win32') {
4346
// On Windows, modern browsers return 'Win32' even if running on a 64-bit version of Windows.
4447
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#usage_notes
4548
return 'Win32';
46-
} else if (process.platform === 'linux') {
47-
if (process.arch === 'ia32') {
49+
} else if (platform === 'linux') {
50+
if (arch === 'ia32') {
4851
return 'Linux i686';
49-
} else if (process.arch === 'x64') {
52+
} else if (arch === 'x64') {
5053
return 'Linux x86_64';
5154
}
52-
return `Linux ${process.arch}`;
53-
} else if (process.platform === 'freebsd') {
54-
if (process.arch === 'ia32') {
55+
return `Linux ${arch}`;
56+
} else if (platform === 'freebsd') {
57+
if (arch === 'ia32') {
5558
return 'FreeBSD i386';
56-
} else if (process.arch === 'x64') {
59+
} else if (arch === 'x64') {
5760
return 'FreeBSD amd64';
5861
}
59-
return `FreeBSD ${process.arch}`;
60-
} else if (process.platform === 'openbsd') {
61-
if (process.arch === 'ia32') {
62+
return `FreeBSD ${arch}`;
63+
} else if (platform === 'openbsd') {
64+
if (arch === 'ia32') {
6265
return 'OpenBSD i386';
63-
} else if (process.arch === 'x64') {
66+
} else if (arch === 'x64') {
6467
return 'OpenBSD amd64';
6568
}
66-
return `OpenBSD ${process.arch}`;
67-
} else if (process.platform === 'sunos') {
68-
if (process.arch === 'ia32') {
69+
return `OpenBSD ${arch}`;
70+
} else if (platform === 'sunos') {
71+
if (arch === 'ia32') {
6972
return 'SunOS i86pc';
7073
}
71-
return `SunOS ${process.arch}`;
72-
} else if (process.platform === 'aix') {
74+
return `SunOS ${arch}`;
75+
} else if (platform === 'aix') {
7376
return 'AIX';
7477
}
75-
return `${StringPrototypeToUpperCase(process.platform[0])}${StringPrototypeSlice(process.platform, 1)} ${process.arch}`;
78+
return `${StringPrototypeToUpperCase(platform[0])}${StringPrototypeSlice(platform, 1)} ${arch}`;
7679
}
7780

7881
class Navigator {
7982
// Private properties are used to avoid brand validations.
8083
#availableParallelism;
8184
#userAgent;
8285
#platform;
83-
#language;
8486
#languages;
8587

8688
constructor() {
@@ -102,8 +104,7 @@ class Navigator {
102104
* @return {string}
103105
*/
104106
get language() {
105-
this.#language ??= Intl?.Collator().resolvedOptions().locale || 'en-US';
106-
return this.#language;
107+
return language;
107108
}
108109

109110
/**
@@ -126,7 +127,7 @@ class Navigator {
126127
* @return {string}
127128
*/
128129
get platform() {
129-
this.#platform ??= getNavigatorPlatform(process);
130+
this.#platform ??= getNavigatorPlatform(arch, platform);
130131
return this.#platform;
131132
}
132133
}

lib/internal/process/per_thread.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const {
4646
validateNumber,
4747
validateObject,
4848
} = require('internal/validators');
49-
const { getValidatedPath } = require('internal/fs/utils');
49+
let getValidatedPath;
5050
const constants = internalBinding('constants').os.signals;
5151

5252
const kInternal = Symbol('internal properties');
@@ -253,6 +253,7 @@ function wrapProcessMethods(binding) {
253253
*/
254254
function loadEnvFile(path = undefined) { // Provide optional value so that `loadEnvFile.length` returns 0
255255
if (path != null) {
256+
getValidatedPath ??= require('internal/fs/utils').getValidatedPath;
256257
path = getValidatedPath(path);
257258
_loadEnvFile(path);
258259
} else {
@@ -421,11 +422,16 @@ function toggleTraceCategoryState(asyncHooksEnabled) {
421422
}
422423
}
423424

425+
const { arch, platform, version } = process;
426+
424427
module.exports = {
425428
toggleTraceCategoryState,
426429
assert,
427430
buildAllowedFlags,
428431
wrapProcessMethods,
429432
hrtime,
430433
hrtimeBigInt,
434+
arch,
435+
platform,
436+
version,
431437
};

lib/internal/process/pre_execution.js

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const {
2020
globalThis,
2121
} = primordials;
2222

23+
const {
24+
Intl,
25+
} = globalThis;
26+
2327
const {
2428
getOptionValue,
2529
refreshOptions,
@@ -327,6 +331,7 @@ function setupNavigator() {
327331

328332
// https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
329333
exposeLazyInterfaces(globalThis, 'internal/navigator', ['Navigator']);
334+
internalBinding('config').language = Intl?.Collator().resolvedOptions().locale || 'en-US';
330335
defineReplaceableLazyAttribute(globalThis, 'internal/navigator', ['navigator'], false);
331336
}
332337

lib/internal/url.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ const {
4949
isWindows,
5050
} = require('internal/util');
5151

52+
const {
53+
platform,
54+
} = require('internal/process/per_thread');
55+
5256
const {
5357
markTransferMode,
5458
} = require('internal/worker/js_transferable');
@@ -1469,7 +1473,7 @@ function getPathFromURLWin32(url) {
14691473

14701474
function getPathFromURLPosix(url) {
14711475
if (url.hostname !== '') {
1472-
throw new ERR_INVALID_FILE_URL_HOST(process.platform);
1476+
throw new ERR_INVALID_FILE_URL_HOST(platform);
14731477
}
14741478
const pathname = url.pathname;
14751479
for (let n = 0; n < pathname.length; n++) {

test/parallel/test-navigator.js

+46-18
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,36 @@
22

33
'use strict';
44

5-
const common = require('../common');
5+
/* eslint node-core/require-common-first: 0 */
6+
67
const assert = require('assert');
8+
9+
{
10+
11+
// Ensures `navigator` has not been evaluated yet
12+
assert.strictEqual(require.resolve('../common') in require.cache, false);
13+
14+
const { version, platform, arch } = process;
15+
try {
16+
let called = false;
17+
Object.defineProperty(process, 'arch', { get() { called += 'arch|'; return arch; } });
18+
Object.defineProperty(process, 'platform', { get() { called = 'platform|'; return platform; } });
19+
Object.defineProperty(process, 'version', { get() { called = 'version|'; return version; } });
20+
21+
navigator; // eslint-disable-line no-unused-expressions
22+
23+
assert.strictEqual(
24+
called,
25+
false
26+
);
27+
} finally {
28+
Object.defineProperty(process, 'arch', { value: arch });
29+
Object.defineProperty(process, 'platform', { value: platform });
30+
Object.defineProperty(process, 'version', { value: version });
31+
}
32+
}
33+
34+
const common = require('../common');
735
const { getNavigatorPlatform } = require('internal/navigator');
836
const { execFile } = require('child_process');
937

@@ -57,23 +85,23 @@ if (process.platform === 'darwin') {
5785
assert.strictEqual(navigator.platform, `${process.platform[0].toUpperCase()}${process.platform.slice(1)} ${process.arch}`);
5886
}
5987

60-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'darwin' }), 'MacIntel');
61-
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'darwin' }), 'MacIntel');
62-
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'linux' }), 'Linux i686');
63-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'linux' }), 'Linux x86_64');
64-
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'linux' }), 'Linux arm64');
65-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'win32' }), 'Win32');
66-
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'win32' }), 'Win32');
67-
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'freebsd' }), 'FreeBSD i386');
68-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'freebsd' }), 'FreeBSD amd64');
69-
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'freebsd' }), 'FreeBSD arm64');
70-
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'openbsd' }), 'OpenBSD i386');
71-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'openbsd' }), 'OpenBSD amd64');
72-
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'openbsd' }), 'OpenBSD arm64');
73-
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'sunos' }), 'SunOS i86pc');
74-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'sunos' }), 'SunOS x64');
75-
assert.strictEqual(getNavigatorPlatform({ arch: 'ppc', platform: 'aix' }), 'AIX');
76-
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'reactos' }), 'Reactos x64');
88+
assert.strictEqual(getNavigatorPlatform('x64', 'darwin'), 'MacIntel');
89+
assert.strictEqual(getNavigatorPlatform('arm64', 'darwin'), 'MacIntel');
90+
assert.strictEqual(getNavigatorPlatform('ia32', 'linux'), 'Linux i686');
91+
assert.strictEqual(getNavigatorPlatform('x64', 'linux'), 'Linux x86_64');
92+
assert.strictEqual(getNavigatorPlatform('arm64', 'linux'), 'Linux arm64');
93+
assert.strictEqual(getNavigatorPlatform('x64', 'win32'), 'Win32');
94+
assert.strictEqual(getNavigatorPlatform('arm64', 'win32'), 'Win32');
95+
assert.strictEqual(getNavigatorPlatform('ia32', 'freebsd'), 'FreeBSD i386');
96+
assert.strictEqual(getNavigatorPlatform('x64', 'freebsd'), 'FreeBSD amd64');
97+
assert.strictEqual(getNavigatorPlatform('arm64', 'freebsd'), 'FreeBSD arm64');
98+
assert.strictEqual(getNavigatorPlatform('ia32', 'openbsd'), 'OpenBSD i386');
99+
assert.strictEqual(getNavigatorPlatform('x64', 'openbsd'), 'OpenBSD amd64');
100+
assert.strictEqual(getNavigatorPlatform('arm64', 'openbsd'), 'OpenBSD arm64');
101+
assert.strictEqual(getNavigatorPlatform('ia32', 'sunos'), 'SunOS i86pc');
102+
assert.strictEqual(getNavigatorPlatform('x64', 'sunos'), 'SunOS x64');
103+
assert.strictEqual(getNavigatorPlatform('ppc', 'aix'), 'AIX');
104+
assert.strictEqual(getNavigatorPlatform('x64', 'reactos'), 'Reactos x64');
77105

78106
assert.strictEqual(typeof navigator.language, 'string');
79107
assert.strictEqual(navigator.language.length !== 0, true);

0 commit comments

Comments
 (0)