Skip to content

Commit 4ab9d6f

Browse files
addaleaxtargos
authored andcommitted
process: generate list of allowed env flags programmatically
Avoids having a separate, second source of truth on this matter. Backport-PR-URL: #22847 PR-URL: #22638 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent ed142e1 commit 4ab9d6f

File tree

5 files changed

+48
-92
lines changed

5 files changed

+48
-92
lines changed

lib/internal/bootstrap/node.js

+42-3
Original file line numberDiff line numberDiff line change
@@ -620,9 +620,45 @@
620620
const test = Function.call.bind(RegExp.prototype.test);
621621

622622
const {
623-
allowedV8EnvironmentFlags,
624-
allowedNodeEnvironmentFlags
625-
} = process.binding('config');
623+
getOptions,
624+
types: { kV8Option },
625+
envSettings: { kAllowedInEnvironment }
626+
} = internalBinding('options');
627+
const { options, aliases } = getOptions();
628+
629+
const allowedV8EnvironmentFlags = [];
630+
const allowedNodeEnvironmentFlags = [];
631+
for (const [name, info] of options) {
632+
if (info.envVarSettings === kAllowedInEnvironment) {
633+
if (info.type === kV8Option) {
634+
allowedV8EnvironmentFlags.push(name);
635+
} else {
636+
allowedNodeEnvironmentFlags.push(name);
637+
}
638+
}
639+
}
640+
641+
for (const [ from, expansion ] of aliases) {
642+
let isAccepted = true;
643+
for (const to of expansion) {
644+
if (!to.startsWith('-')) continue;
645+
const recursiveExpansion = aliases.get(to);
646+
if (recursiveExpansion) {
647+
expansion.push(...recursiveExpansion);
648+
continue;
649+
}
650+
isAccepted = options.get(to).envVarSettings === kAllowedInEnvironment;
651+
if (!isAccepted) break;
652+
}
653+
if (isAccepted) {
654+
let canonical = from;
655+
if (canonical.endsWith('='))
656+
canonical = canonical.substr(0, canonical.length - 1);
657+
if (canonical.endsWith(' <arg>'))
658+
canonical = canonical.substr(0, canonical.length - 4);
659+
allowedNodeEnvironmentFlags.push(canonical);
660+
}
661+
}
626662

627663
const trimLeadingDashes = (flag) => replace(flag, leadingDashesRegex, '');
628664

@@ -660,6 +696,9 @@
660696
// permutations of a flag, including present/missing leading
661697
// dash(es) and/or underscores-for-dashes in the case of V8-specific
662698
// flags. Strips any values after `=`, inclusive.
699+
// TODO(addaleax): It might be more flexible to run the option parser
700+
// on a dummy option set and see whether it rejects the argument or
701+
// not.
663702
if (typeof key === 'string') {
664703
key = replace(key, trailingValuesRegex, '');
665704
if (test(leadingDashesRegex, key)) {

src/node.cc

-62
Original file line numberDiff line numberDiff line change
@@ -597,68 +597,6 @@ const char* signo_string(int signo) {
597597
}
598598
}
599599

600-
// These are all flags available for use with NODE_OPTIONS.
601-
//
602-
// Disallowed flags:
603-
// These flags cause Node to do things other than run scripts:
604-
// --version / -v
605-
// --eval / -e
606-
// --print / -p
607-
// --check / -c
608-
// --interactive / -i
609-
// --prof-process
610-
// --v8-options
611-
// These flags are disallowed because security:
612-
// --preserve-symlinks
613-
const char* const environment_flags[] = {
614-
// Node options, sorted in `node --help` order for ease of comparison.
615-
"--enable-fips",
616-
"--experimental-modules",
617-
"--experimenatl-repl-await",
618-
"--experimental-vm-modules",
619-
"--experimental-worker",
620-
"--force-fips",
621-
"--icu-data-dir",
622-
"--inspect",
623-
"--inspect-brk",
624-
"--inspect-port",
625-
"--loader",
626-
"--napi-modules",
627-
"--no-deprecation",
628-
"--no-force-async-hooks-checks",
629-
"--no-warnings",
630-
"--openssl-config",
631-
"--pending-deprecation",
632-
"--redirect-warnings",
633-
"--require",
634-
"--throw-deprecation",
635-
"--tls-cipher-list",
636-
"--trace-deprecation",
637-
"--trace-event-categories",
638-
"--trace-event-file-pattern",
639-
"--trace-events-enabled",
640-
"--trace-sync-io",
641-
"--trace-warnings",
642-
"--track-heap-objects",
643-
"--use-bundled-ca",
644-
"--use-openssl-ca",
645-
"--v8-pool-size",
646-
"--zero-fill-buffers",
647-
"-r"
648-
};
649-
650-
// V8 options (define with '_', which allows '-' or '_')
651-
const char* const v8_environment_flags[] = {
652-
"--abort_on_uncaught_exception",
653-
"--max_old_space_size",
654-
"--perf_basic_prof",
655-
"--perf_prof",
656-
"--stack_trace_limit",
657-
};
658-
659-
int v8_environment_flags_count = arraysize(v8_environment_flags);
660-
int environment_flags_count = arraysize(environment_flags);
661-
662600
// Look up environment variable unless running as setuid root.
663601
bool SafeGetenv(const char* key, std::string* text) {
664602
#if !defined(__CloudABI__) && !defined(_WIN32)

src/node_config.cc

-17
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
namespace node {
77

8-
using v8::Array;
98
using v8::Boolean;
109
using v8::Context;
1110
using v8::Integer;
@@ -137,22 +136,6 @@ static void Initialize(Local<Object> target,
137136
READONLY_PROPERTY(debug_options_obj,
138137
"inspectorEnabled",
139138
Boolean::New(isolate, debug_options->inspector_enabled));
140-
141-
Local<Array> environmentFlags = Array::New(env->isolate(),
142-
environment_flags_count);
143-
READONLY_PROPERTY(target, "allowedNodeEnvironmentFlags", environmentFlags);
144-
for (int i = 0; i < environment_flags_count; ++i) {
145-
environmentFlags->Set(i, OneByteString(env->isolate(),
146-
environment_flags[i]));
147-
}
148-
149-
Local<Array> v8EnvironmentFlags = Array::New(env->isolate(),
150-
v8_environment_flags_count);
151-
READONLY_PROPERTY(target, "allowedV8EnvironmentFlags", v8EnvironmentFlags);
152-
for (int i = 0; i < v8_environment_flags_count; ++i) {
153-
v8EnvironmentFlags->Set(i, OneByteString(env->isolate(),
154-
v8_environment_flags[i]));
155-
}
156139
} // InitConfig
157140

158141
} // namespace node

src/node_internals.h

-5
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,6 @@ extern bool v8_initialized;
180180
extern Mutex per_process_opts_mutex;
181181
extern std::shared_ptr<PerProcessOptions> per_process_opts;
182182

183-
extern const char* const environment_flags[];
184-
extern int environment_flags_count;
185-
extern const char* const v8_environment_flags[];
186-
extern int v8_environment_flags_count;
187-
188183
// Forward declaration
189184
class Environment;
190185

test/parallel/test-process-env-allowed-flags.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ require('../common');
66
// assert legit flags are allowed, and bogus flags are disallowed
77
{
88
const goodFlags = [
9-
'--inspect-brk',
10-
'inspect-brk',
119
'--perf_basic_prof',
1210
'--perf-basic-prof',
1311
'perf-basic-prof',
@@ -17,8 +15,11 @@ require('../common');
1715
'-r',
1816
'r',
1917
'--stack-trace-limit=100',
20-
'--stack-trace-limit=-=xX_nodejs_Xx=-'
21-
];
18+
'--stack-trace-limit=-=xX_nodejs_Xx=-',
19+
].concat(process.config.variables.v8_enable_inspector ? [
20+
'--inspect-brk',
21+
'inspect-brk',
22+
] : []);
2223

2324
const badFlags = [
2425
'--inspect_brk',
@@ -50,7 +51,7 @@ require('../common');
5051
// assert all "canonical" flags begin with dash(es)
5152
{
5253
process.allowedNodeEnvironmentFlags.forEach((flag) => {
53-
assert(/^--?[a-z8_-]+$/.test(flag), `Unexpected format for flag ${flag}`);
54+
assert(/^--?[a-z28_-]+$/.test(flag), `Unexpected format for flag ${flag}`);
5455
});
5556
}
5657

0 commit comments

Comments
 (0)