Skip to content

Commit

Permalink
lib: make navigator not runtime-lookup process.version/arch/platform
Browse files Browse the repository at this point in the history
Preserves most of #53649,
except for `#language` due to the lack of Intl primordials.
  • Loading branch information
ljharb committed Jul 8, 2024
1 parent b9289a6 commit 0acb361
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 54 deletions.
4 changes: 4 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
46 changes: 24 additions & 22 deletions lib/internal/navigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,52 +27,54 @@ 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

Check warning on line 35 in lib/internal/navigator.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected @param names to be "arch, platform". Got "process"
* @param {string} process.platform
* @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 {
Expand Down Expand Up @@ -126,7 +128,7 @@ class Navigator {
* @return {string}
*/
get platform() {
this.#platform ??= getNavigatorPlatform(process);
this.#platform ??= getNavigatorPlatform(arch, platform);
return this.#platform;
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/internal/process/arch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('process').arch;
3 changes: 3 additions & 0 deletions lib/internal/process/platform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('process').platform;
3 changes: 3 additions & 0 deletions lib/internal/process/version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('process').version;
32 changes: 18 additions & 14 deletions test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
64 changes: 46 additions & 18 deletions test/parallel/test-navigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 0acb361

Please sign in to comment.