diff --git a/src/node_worker.cc b/src/node_worker.cc index 9e2999ed8c3955..048f15aea1cbc1 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -485,46 +485,44 @@ void Worker::New(const FunctionCallbackInfo& args) { env_vars = env->env_vars(); } - if (args[1]->IsObject() || args[2]->IsArray()) { - per_isolate_opts.reset(new PerIsolateOptions()); + per_isolate_opts.reset(new PerIsolateOptions()); - HandleEnvOptions(per_isolate_opts->per_env, [&env_vars](const char* name) { - return env_vars->Get(name).FromMaybe(""); - }); + HandleEnvOptions(per_isolate_opts->per_env, [&env_vars](const char* name) { + return env_vars->Get(name).FromMaybe(""); + }); #ifndef NODE_WITHOUT_NODE_OPTIONS - MaybeLocal maybe_node_opts = - env_vars->Get(isolate, OneByteString(isolate, "NODE_OPTIONS")); - Local node_opts; - if (maybe_node_opts.ToLocal(&node_opts)) { - std::string node_options(*String::Utf8Value(isolate, node_opts)); - std::vector errors{}; - std::vector env_argv = - ParseNodeOptionsEnvVar(node_options, &errors); - // [0] is expected to be the program name, add dummy string. - env_argv.insert(env_argv.begin(), ""); - std::vector invalid_args{}; - options_parser::Parse(&env_argv, - nullptr, - &invalid_args, - per_isolate_opts.get(), - kAllowedInEnvironment, - &errors); - if (!errors.empty() && args[1]->IsObject()) { - // Only fail for explicitly provided env, this protects from failures - // when NODE_OPTIONS from parent's env is used (which is the default). - Local error; - if (!ToV8Value(env->context(), errors).ToLocal(&error)) return; - Local key = - FIXED_ONE_BYTE_STRING(env->isolate(), "invalidNodeOptions"); - // Ignore the return value of Set() because exceptions bubble up to JS - // when we return anyway. - USE(args.This()->Set(env->context(), key, error)); - return; - } + MaybeLocal maybe_node_opts = + env_vars->Get(isolate, OneByteString(isolate, "NODE_OPTIONS")); + Local node_opts; + if (maybe_node_opts.ToLocal(&node_opts)) { + std::string node_options(*String::Utf8Value(isolate, node_opts)); + std::vector errors{}; + std::vector env_argv = + ParseNodeOptionsEnvVar(node_options, &errors); + // [0] is expected to be the program name, add dummy string. + env_argv.insert(env_argv.begin(), ""); + std::vector invalid_args{}; + options_parser::Parse(&env_argv, + nullptr, + &invalid_args, + per_isolate_opts.get(), + kAllowedInEnvironment, + &errors); + if (!errors.empty() && args[1]->IsObject()) { + // Only fail for explicitly provided env, this protects from failures + // when NODE_OPTIONS from parent's env is used (which is the default). + Local error; + if (!ToV8Value(env->context(), errors).ToLocal(&error)) return; + Local key = + FIXED_ONE_BYTE_STRING(env->isolate(), "invalidNodeOptions"); + // Ignore the return value of Set() because exceptions bubble up to JS + // when we return anyway. + USE(args.This()->Set(env->context(), key, error)); + return; } -#endif // NODE_WITHOUT_NODE_OPTIONS } +#endif // NODE_WITHOUT_NODE_OPTIONS if (args[2]->IsArray()) { Local array = args[2].As(); diff --git a/test/fixtures/assert-global.js b/test/fixtures/assert-global.js new file mode 100644 index 00000000000000..40b3ab566fcec0 --- /dev/null +++ b/test/fixtures/assert-global.js @@ -0,0 +1,3 @@ +'use strict'; +const assert = require('assert'); +assert.strictEqual(global.a, 'test'); diff --git a/test/parallel/test-worker-process-env-options.js b/test/parallel/test-worker-process-env-options.js new file mode 100644 index 00000000000000..0dba089d573977 --- /dev/null +++ b/test/parallel/test-worker-process-env-options.js @@ -0,0 +1,11 @@ +'use strict'; + +require('../common'); + +const fixtures = require('../common/fixtures'); +const { Worker } = require('node:worker_threads'); + +process.env.NODE_OPTIONS ??= ''; +process.env.NODE_OPTIONS += ` --require ${JSON.stringify(fixtures.path('define-global.js'))}`; + +new Worker(fixtures.path('assert-global.js'));