mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
lib: generate allowedNodeEnvironmentFlags lazily
PR-URL: https://github.com/nodejs/node/pull/22638 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
1 file changed
+120
-105
+120
-105
@@ -670,117 +670,132 @@
|
||||
const has = Function.call.bind(Set.prototype.has);
|
||||
const test = Function.call.bind(RegExp.prototype.test);
|
||||
|
||||
const {
|
||||
getOptions,
|
||||
types: { kV8Option },
|
||||
envSettings: { kAllowedInEnvironment }
|
||||
} = internalBinding('options');
|
||||
const { options, aliases } = getOptions();
|
||||
const get = () => {
|
||||
const {
|
||||
getOptions,
|
||||
types: { kV8Option },
|
||||
envSettings: { kAllowedInEnvironment }
|
||||
} = internalBinding('options');
|
||||
const { options, aliases } = getOptions();
|
||||
|
||||
const allowedV8EnvironmentFlags = [];
|
||||
const allowedNodeEnvironmentFlags = [];
|
||||
for (const [name, info] of options) {
|
||||
if (info.envVarSettings === kAllowedInEnvironment) {
|
||||
if (info.type === kV8Option) {
|
||||
allowedV8EnvironmentFlags.push(name);
|
||||
} else {
|
||||
allowedNodeEnvironmentFlags.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [ from, expansion ] of aliases) {
|
||||
let isAccepted = true;
|
||||
for (const to of expansion) {
|
||||
if (!to.startsWith('-')) continue;
|
||||
const recursiveExpansion = aliases.get(to);
|
||||
if (recursiveExpansion) {
|
||||
expansion.push(...recursiveExpansion);
|
||||
continue;
|
||||
}
|
||||
isAccepted = options.get(to).envVarSettings === kAllowedInEnvironment;
|
||||
if (!isAccepted) break;
|
||||
}
|
||||
if (isAccepted) {
|
||||
let canonical = from;
|
||||
if (canonical.endsWith('='))
|
||||
canonical = canonical.substr(0, canonical.length - 1);
|
||||
if (canonical.endsWith(' <arg>'))
|
||||
canonical = canonical.substr(0, canonical.length - 4);
|
||||
allowedNodeEnvironmentFlags.push(canonical);
|
||||
}
|
||||
}
|
||||
|
||||
const trimLeadingDashes = (flag) => replace(flag, leadingDashesRegex, '');
|
||||
|
||||
// Save these for comparison against flags provided to
|
||||
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
|
||||
// Avoid interference w/ user code by flattening `Set.prototype` into
|
||||
// each object.
|
||||
const [nodeFlags, v8Flags] = [
|
||||
allowedNodeEnvironmentFlags, allowedV8EnvironmentFlags
|
||||
].map((flags) => Object.defineProperties(
|
||||
new Set(flags.map(trimLeadingDashes)),
|
||||
Object.getOwnPropertyDescriptors(Set.prototype))
|
||||
);
|
||||
|
||||
class NodeEnvironmentFlagsSet extends Set {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
// the super constructor consumes `add`, but
|
||||
// disallow any future adds.
|
||||
this.add = () => this;
|
||||
}
|
||||
|
||||
delete() {
|
||||
// noop, `Set` API compatible
|
||||
return false;
|
||||
}
|
||||
|
||||
clear() {
|
||||
// noop
|
||||
}
|
||||
|
||||
has(key) {
|
||||
// This will return `true` based on various possible
|
||||
// permutations of a flag, including present/missing leading
|
||||
// dash(es) and/or underscores-for-dashes in the case of V8-specific
|
||||
// flags. Strips any values after `=`, inclusive.
|
||||
// TODO(addaleax): It might be more flexible to run the option parser
|
||||
// on a dummy option set and see whether it rejects the argument or
|
||||
// not.
|
||||
if (typeof key === 'string') {
|
||||
key = replace(key, trailingValuesRegex, '');
|
||||
if (test(leadingDashesRegex, key)) {
|
||||
return has(this, key) ||
|
||||
has(v8Flags,
|
||||
replace(
|
||||
replace(
|
||||
key,
|
||||
leadingDashesRegex,
|
||||
''
|
||||
),
|
||||
replaceDashesRegex,
|
||||
'_'
|
||||
)
|
||||
);
|
||||
const allowedV8EnvironmentFlags = [];
|
||||
const allowedNodeEnvironmentFlags = [];
|
||||
for (const [name, info] of options) {
|
||||
if (info.envVarSettings === kAllowedInEnvironment) {
|
||||
if (info.type === kV8Option) {
|
||||
allowedV8EnvironmentFlags.push(name);
|
||||
} else {
|
||||
allowedNodeEnvironmentFlags.push(name);
|
||||
}
|
||||
return has(nodeFlags, key) ||
|
||||
has(v8Flags, replace(key, replaceDashesRegex, '_'));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Object.freeze(NodeEnvironmentFlagsSet.prototype.constructor);
|
||||
Object.freeze(NodeEnvironmentFlagsSet.prototype);
|
||||
for (const [ from, expansion ] of aliases) {
|
||||
let isAccepted = true;
|
||||
for (const to of expansion) {
|
||||
if (!to.startsWith('-')) continue;
|
||||
const recursiveExpansion = aliases.get(to);
|
||||
if (recursiveExpansion) {
|
||||
expansion.push(...recursiveExpansion);
|
||||
continue;
|
||||
}
|
||||
isAccepted = options.get(to).envVarSettings === kAllowedInEnvironment;
|
||||
if (!isAccepted) break;
|
||||
}
|
||||
if (isAccepted) {
|
||||
let canonical = from;
|
||||
if (canonical.endsWith('='))
|
||||
canonical = canonical.substr(0, canonical.length - 1);
|
||||
if (canonical.endsWith(' <arg>'))
|
||||
canonical = canonical.substr(0, canonical.length - 4);
|
||||
allowedNodeEnvironmentFlags.push(canonical);
|
||||
}
|
||||
}
|
||||
|
||||
process.allowedNodeEnvironmentFlags = Object.freeze(
|
||||
new NodeEnvironmentFlagsSet(
|
||||
allowedNodeEnvironmentFlags.concat(allowedV8EnvironmentFlags)
|
||||
)
|
||||
);
|
||||
const trimLeadingDashes = (flag) => replace(flag, leadingDashesRegex, '');
|
||||
|
||||
// Save these for comparison against flags provided to
|
||||
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
|
||||
// Avoid interference w/ user code by flattening `Set.prototype` into
|
||||
// each object.
|
||||
const [nodeFlags, v8Flags] = [
|
||||
allowedNodeEnvironmentFlags, allowedV8EnvironmentFlags
|
||||
].map((flags) => Object.defineProperties(
|
||||
new Set(flags.map(trimLeadingDashes)),
|
||||
Object.getOwnPropertyDescriptors(Set.prototype))
|
||||
);
|
||||
|
||||
class NodeEnvironmentFlagsSet extends Set {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
// the super constructor consumes `add`, but
|
||||
// disallow any future adds.
|
||||
this.add = () => this;
|
||||
}
|
||||
|
||||
delete() {
|
||||
// noop, `Set` API compatible
|
||||
return false;
|
||||
}
|
||||
|
||||
clear() {
|
||||
// noop
|
||||
}
|
||||
|
||||
has(key) {
|
||||
// This will return `true` based on various possible
|
||||
// permutations of a flag, including present/missing leading
|
||||
// dash(es) and/or underscores-for-dashes in the case of V8-specific
|
||||
// flags. Strips any values after `=`, inclusive.
|
||||
// TODO(addaleax): It might be more flexible to run the option parser
|
||||
// on a dummy option set and see whether it rejects the argument or
|
||||
// not.
|
||||
if (typeof key === 'string') {
|
||||
key = replace(key, trailingValuesRegex, '');
|
||||
if (test(leadingDashesRegex, key)) {
|
||||
return has(this, key) ||
|
||||
has(v8Flags,
|
||||
replace(
|
||||
replace(
|
||||
key,
|
||||
leadingDashesRegex,
|
||||
''
|
||||
),
|
||||
replaceDashesRegex,
|
||||
'_'
|
||||
)
|
||||
);
|
||||
}
|
||||
return has(nodeFlags, key) ||
|
||||
has(v8Flags, replace(key, replaceDashesRegex, '_'));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Object.freeze(NodeEnvironmentFlagsSet.prototype.constructor);
|
||||
Object.freeze(NodeEnvironmentFlagsSet.prototype);
|
||||
|
||||
return process.allowedNodeEnvironmentFlags = Object.freeze(
|
||||
new NodeEnvironmentFlagsSet(
|
||||
allowedNodeEnvironmentFlags.concat(allowedV8EnvironmentFlags)
|
||||
));
|
||||
};
|
||||
|
||||
Object.defineProperty(process, 'allowedNodeEnvironmentFlags', {
|
||||
get,
|
||||
set(value) {
|
||||
Object.defineProperty(this, 'allowedNodeEnvironmentFlags', {
|
||||
value,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true
|
||||
});
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
startup();
|
||||
|
||||
Reference in new issue
Block a user