From 86ee17a6cb7de8669d754a077fc54fefdbdcdbaf Mon Sep 17 00:00:00 2001 From: Archkon <180910180+Archkon@users.noreply.github.com> Date: Sat, 1 Aug 2026 18:32:44 +0800 Subject: [PATCH] src: override inherited task runner environment Filter inherited NODE_RUN_SCRIPT_NAME and NODE_RUN_PACKAGE_JSON_PATH before adding the current task values. This prevents duplicate environment entries during nested node --run invocations. Signed-off-by: Archkon <180910180+Archkon@users.noreply.github.com> --- src/node_task_runner.cc | 15 +++++++++++++++ test/parallel/test-node-run.js | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/node_task_runner.cc b/src/node_task_runner.cc index 22c02e83e12e..7d05d8f90b91 100644 --- a/src/node_task_runner.cc +++ b/src/node_task_runner.cc @@ -11,6 +11,15 @@ static constexpr const char* env_var_separator = ";"; static constexpr const char* env_var_separator = ":"; #endif // _WIN32 +static bool IsNodeRunEnvironmentVariable(const std::string& name) { +#ifdef _WIN32 + return StringEqualNoCase(name.c_str(), "NODE_RUN_SCRIPT_NAME") || + StringEqualNoCase(name.c_str(), "NODE_RUN_PACKAGE_JSON_PATH"); +#else + return name == "NODE_RUN_SCRIPT_NAME" || name == "NODE_RUN_PACKAGE_JSON_PATH"; +#endif // _WIN32 +} + ProcessRunner::ProcessRunner(std::shared_ptr result, const std::filesystem::path& package_json_path, std::string_view script_name, @@ -108,6 +117,12 @@ void ProcessRunner::SetEnvironmentVariables() { } #endif // _WIN32 + // These variables describe the current task and are added below. Do not + // retain inherited values, as that would create duplicate entries. + if (IsNodeRunEnvironmentVariable(name)) { + continue; + } + if (StringEqualNoCase(name.c_str(), "path")) { // Add path env variable to the beginning of the PATH value = path_env_var_ + value; diff --git a/test/parallel/test-node-run.js b/test/parallel/test-node-run.js index e24117f6b165..05e072fa5e42 100644 --- a/test/parallel/test-node-run.js +++ b/test/parallel/test-node-run.js @@ -189,6 +189,29 @@ describe('node --run [command]', () => { assert.strictEqual(child.code, 0); }); + it('should override inherited special environment variables', async () => { + const scriptName = `special-env-variables${envSuffix}`; + const packageJsonPath = fixtures.path('run-script/package.json'); + const child = await common.spawnPromisified( + process.execPath, + [ '--run', scriptName], + { + cwd: fixtures.path('run-script'), + env: { + ...process.env, + NODE_RUN_SCRIPT_NAME: 'inherited-script-name', + NODE_RUN_PACKAGE_JSON_PATH: 'inherited-package-json-path', + }, + }, + ); + assert.deepStrictEqual(child.stdout.trim().split(/\r?\n/), [ + scriptName, + packageJsonPath, + ]); + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.code, 0); + }); + it('will search parent directories for a package.json file', async () => { const packageJsonPath = fixtures.path('run-script/package.json'); const child = await common.spawnPromisified(