diff --git a/src/node_task_runner.cc b/src/node_task_runner.cc index 2b3e005abf34..b3f3fddb4152 100644 --- a/src/node_task_runner.cc +++ b/src/node_task_runner.cc @@ -227,7 +227,8 @@ FindPackageJson(const std::filesystem::path& cwd) { directory_path = directory_path.parent_path()) { // Append "path/node_modules/.bin" to the env var, if it is a directory. auto node_modules_bin = directory_path / "node_modules" / ".bin"; - if (std::filesystem::is_directory(node_modules_bin)) { + std::error_code error; + if (std::filesystem::is_directory(node_modules_bin, error)) { path_env_var += ConvertPathToUTF8(node_modules_bin) + env_var_separator; } diff --git a/test/parallel/test-node-run.js b/test/parallel/test-node-run.js index 7c1f6609f6f1..f4e448b46769 100644 --- a/test/parallel/test-node-run.js +++ b/test/parallel/test-node-run.js @@ -243,6 +243,33 @@ describe('node --run [command]', () => { assert.strictEqual(output.path.split(path.delimiter)[0], nodeModulesBin); }); + it('skips inaccessible node_modules directories', { + skip: common.isWindows || common.isIBMi || process.getuid?.() === 0, + }, async () => { + tmpdir.refresh(); + const nodeModules = tmpdir.resolve('node_modules'); + fs.mkdirSync(nodeModules); + fs.writeFileSync(tmpdir.resolve('package.json'), JSON.stringify({ + scripts: { test: 'echo ok' }, + })); + fs.chmodSync(nodeModules, 0o000); + + let child; + try { + child = await common.spawnPromisified( + process.execPath, + [ '--run', 'test'], + { cwd: tmpdir.path }, + ); + } finally { + fs.chmodSync(nodeModules, 0o700); + } + + assert.strictEqual(child.stdout, 'ok\n'); + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.code, 0); + }); + it('returns error on unparsable file', async () => { const child = await common.spawnPromisified( process.execPath,