From 452bedf6731dea617570b7bc93aa0ebc25d50f5f Mon Sep 17 00:00:00 2001 From: theanarkh Date: Sat, 4 May 2024 13:17:48 +0800 Subject: [PATCH] src: make sure pass the cli_options to worker --- src/node_worker.cc | 64 ++++++++++++------------ test/parallel/test-worker-cli-options.js | 12 +++++ 2 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 test/parallel/test-worker-cli-options.js diff --git a/src/node_worker.cc b/src/node_worker.cc index 196eb3bccaee87..ef04a2a08e17e7 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -534,6 +534,7 @@ void Worker::New(const FunctionCallbackInfo& args) { } if (args[1]->IsObject() || args[2]->IsArray()) { + Mutex::ScopedLock lock(per_process::cli_options_mutex); per_isolate_opts.reset(new PerIsolateOptions()); HandleEnvOptions(per_isolate_opts->per_env, [&env_vars](const char* name) { @@ -570,12 +571,11 @@ void Worker::New(const FunctionCallbackInfo& args) { } #endif // NODE_WITHOUT_NODE_OPTIONS } - + // The first argument is reserved for program name, but we don't need it + // in workers. + std::vector exec_argv = {""}; if (args[2]->IsArray()) { Local array = args[2].As(); - // The first argument is reserved for program name, but we don't need it - // in workers. - std::vector exec_argv = {""}; uint32_t length = array->Length(); for (uint32_t i = 0; i < length; i++) { Local arg; @@ -590,38 +590,38 @@ void Worker::New(const FunctionCallbackInfo& args) { std::string arg_string(arg_utf8_value.out(), arg_utf8_value.length()); exec_argv.push_back(arg_string); } - - std::vector invalid_args{}; - std::vector errors{}; - // Using invalid_args as the v8_args argument as it stores unknown - // options for the per isolate parser. - options_parser::Parse(&exec_argv, - &exec_argv_out, - &invalid_args, - per_isolate_opts.get(), - kDisallowedInEnvvar, - &errors); - - // The first argument is program name. - invalid_args.erase(invalid_args.begin()); - if (errors.size() > 0 || invalid_args.size() > 0) { - Local error; - if (!ToV8Value(env->context(), - errors.size() > 0 ? errors : invalid_args) - .ToLocal(&error)) { - return; - } - Local key = - FIXED_ONE_BYTE_STRING(env->isolate(), "invalidExecArgv"); - // 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; - } } else { exec_argv_out = env->exec_argv(); + exec_argv.insert(exec_argv.end(), exec_argv_out.begin(), exec_argv_out.end()); } + std::vector invalid_args{}; + std::vector errors{}; + // Using invalid_args as the v8_args argument as it stores unknown + // options for the per isolate parser. + options_parser::Parse(&exec_argv, + &exec_argv_out, + &invalid_args, + per_isolate_opts.get(), + kDisallowedInEnvvar, + &errors); + + // The first argument is program name. + invalid_args.erase(invalid_args.begin()); + if (errors.size() > 0 || invalid_args.size() > 0) { + Local error; + if (!ToV8Value(env->context(), + errors.size() > 0 ? errors : invalid_args) + .ToLocal(&error)) { + return; + } + Local key = + FIXED_ONE_BYTE_STRING(env->isolate(), "invalidExecArgv"); + // 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; + } const SnapshotData* snapshot_data = env->isolate_data()->snapshot_data(); Worker* worker = new Worker(env, diff --git a/test/parallel/test-worker-cli-options.js b/test/parallel/test-worker-cli-options.js new file mode 100644 index 00000000000000..4299c5f054cb12 --- /dev/null +++ b/test/parallel/test-worker-cli-options.js @@ -0,0 +1,12 @@ +// Flags: --expose-internals +'use strict'; +require('../common'); +const { Worker } = require('worker_threads'); + +// Test if the flags is passed to worker threads +// See https://github.com/nodejs/node/issues/52825 +new Worker(` + // If the --expose-internals flag does not pass to worker + // require function will throw an error + require('internal/options'); +`, { eval: true, env: process.env });