Files
node/test/parallel/test-module-unreadable-package-json.js
greenhead 0e5f4b64dc test: use common spawnSync helpers in more tests
The helpers report the command, both streams, and the exit condition
on failure, so mismatches are diagnosed consistently across tests.

Signed-off-by: greenhead <greenheadhq@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65552
Refs: https://github.com/nodejs/node/pull/65377
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-08-28 09:26:21 +00:00

58 lines
2.0 KiB
JavaScript

'use strict';
// A package.json that exists but cannot be read must not be treated as
// absent. Doing so silently drops fields such as "exports", which can resolve
// a specifier to a different file than the one the package declares.
// Refs: https://github.com/nodejs/node/issues/65220
const common = require('../common');
if (common.isWindows) {
common.skip('chmod does not restrict reads on Windows');
}
if (process.getuid?.() === 0) {
common.skip('cannot make a file unreadable as root');
}
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
const { spawnSyncAndAssert } = require('../common/child_process');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
const depDir = tmpdir.resolve('node_modules/dep');
fs.mkdirSync(path.join(depDir, 'lib'), { recursive: true });
const depPackageJson = path.join(depDir, 'package.json');
fs.writeFileSync(
depPackageJson,
'{"name":"dep","exports":{".":"./lib/real.js"}}',
);
fs.writeFileSync(path.join(depDir, 'lib', 'real.js'), 'export const which = "real";');
// If the package config is ignored, resolution falls back to this file.
fs.writeFileSync(path.join(depDir, 'index.js'), 'export const which = "decoy";');
fs.writeFileSync(tmpdir.resolve('package.json'), '{"type":"module"}');
const entry = tmpdir.resolve('main.mjs');
fs.writeFileSync(entry, 'import { which } from "dep"; console.log(which);');
// Sanity check: the export resolves while the package config is readable.
spawnSyncAndAssert(process.execPath, [entry], { encoding: 'utf8' }, {
stdout: 'real',
trim: true,
});
fs.chmodSync(depPackageJson, 0o000);
try {
const child = spawnSync(process.execPath, [entry], { encoding: 'utf8' });
// The read failure must be reported rather than resolving to index.js.
assert.doesNotMatch(child.stdout, /decoy/);
assert.match(child.stderr, /Cannot read package config/);
assert.notStrictEqual(child.status, 0);
} finally {
fs.chmodSync(depPackageJson, 0o644);
}