Skip to content

Commit

Permalink
process: disallow adding options to process.allowedNodeEnvironmentFlags
Browse files Browse the repository at this point in the history
Make no-op direct calls of `Set` prototype methods to
`process.allowedNodeEnvironmentFlags`.

```js
const { add } = Set.prototype;
add.call(process.allowedNodeEnvironmentFlags, '--user-option`);
process.allowedNodeEnvironmentFlags.has('--user-option') === false;
```
  • Loading branch information
aduh95 committed Feb 1, 2021
1 parent b5f5c46 commit 6262973
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 23 deletions.
58 changes: 41 additions & 17 deletions lib/internal/process/per_thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,24 @@

const {
ArrayPrototypeEvery,
ArrayPrototypeIncludes,
ArrayPrototypeMap,
ArrayPrototypePush,
ArrayPrototypeSplice,
BigUint64Array,
Float64Array,
NumberMAX_SAFE_INTEGER,
ObjectDefineProperty,
ObjectFreeze,
ReflectApply,
RegExpPrototypeTest,
SafeSet,
SafeArrayIterator,
Set,
StringPrototypeEndsWith,
StringPrototypeReplace,
StringPrototypeSlice,
StringPrototypeStartsWith,
Symbol,
SymbolIterator,
Uint32Array,
} = primordials;

Expand All @@ -41,6 +44,8 @@ const {
} = require('internal/validators');
const constants = internalBinding('constants').os.signals;

const kSet = Symbol('internal set');

function assert(x, msg) {
if (!x) throw new ERR_ASSERTION(msg || 'assertion error');
}
Expand Down Expand Up @@ -293,18 +298,18 @@ function buildAllowedFlags() {

// Save these for comparison against flags provided to
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
const nodeFlags = new SafeSet(ArrayPrototypeMap(allowedNodeEnvironmentFlags,
trimLeadingDashes));

class NodeEnvironmentFlagsSet extends SafeSet {
constructor(...args) {
super(...args);

// The super constructor consumes `add`, but
// disallow any future adds.
ObjectDefineProperty(this, 'add', {
value: () => this
});
const nodeFlags = ArrayPrototypeMap(allowedNodeEnvironmentFlags,
trimLeadingDashes);

class NodeEnvironmentFlagsSet extends Set {
constructor(iterable) {
super();
this[kSet] = new Set(new SafeArrayIterator(iterable));
}

add() {
// No-op, `Set` API compatible
return this;
}

delete() {
Expand All @@ -313,7 +318,7 @@ function buildAllowedFlags() {
}

clear() {
// No-op
// No-op, `Set` API compatible
}

has(key) {
Expand All @@ -328,13 +333,32 @@ function buildAllowedFlags() {
key = StringPrototypeReplace(key, replaceUnderscoresRegex, '-');
if (RegExpPrototypeTest(leadingDashesRegex, key)) {
key = StringPrototypeReplace(key, trailingValuesRegex, '');
return super.has(key);
return this[kSet].has(key);
}
return nodeFlags.has(key);
return ArrayPrototypeIncludes(nodeFlags, key);
}
return false;
}

entries() {
return this[kSet].entries();
}

forEach(callback, thisArg = undefined) {
this[kSet].forEach((v) => ReflectApply(callback, thisArg, [v, v, this]));
}

get size() {
return this[kSet].size;
}

values() {
return this[kSet].values();
}
}
NodeEnvironmentFlagsSet.prototype.keys =
NodeEnvironmentFlagsSet.prototype[SymbolIterator] =
NodeEnvironmentFlagsSet.prototype.values;

ObjectFreeze(NodeEnvironmentFlagsSet.prototype.constructor);
ObjectFreeze(NodeEnvironmentFlagsSet.prototype);
Expand Down
38 changes: 32 additions & 6 deletions test/parallel/test-process-env-allowed-flags.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

require('../common');
const common = require('../common');
const assert = require('assert');

// Assert legit flags are allowed, and bogus flags are disallowed
Expand Down Expand Up @@ -62,15 +62,41 @@ const assert = require('assert');
true);

process.allowedNodeEnvironmentFlags.add('foo');
Set.prototype.add.call(process.allowedNodeEnvironmentFlags, 'foo');
assert.strictEqual(process.allowedNodeEnvironmentFlags.has('foo'), false);
process.allowedNodeEnvironmentFlags.forEach((flag) => {
assert.strictEqual(flag === 'foo', false);
});

process.allowedNodeEnvironmentFlags.clear();
assert.strictEqual(process.allowedNodeEnvironmentFlags.size > 0, true);
const thisArg = {};
process.allowedNodeEnvironmentFlags.forEach(
common.mustCallAtLeast(function(flag, _, set) {
assert.notStrictEqual(flag, 'foo');
assert.strictEqual(this, thisArg);
assert.strictEqual(set, process.allowedNodeEnvironmentFlags);
}),
thisArg
);

for (const flag of process.allowedNodeEnvironmentFlags.keys()) {
assert.notStrictEqual(flag, 'foo');
}
for (const flag of process.allowedNodeEnvironmentFlags.values()) {
assert.notStrictEqual(flag, 'foo');
}
for (const flag of process.allowedNodeEnvironmentFlags) {
assert.notStrictEqual(flag, 'foo');
}
for (const [flag] of process.allowedNodeEnvironmentFlags.entries()) {
assert.notStrictEqual(flag, 'foo');
}

const size = process.allowedNodeEnvironmentFlags.size;

process.allowedNodeEnvironmentFlags.clear();
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
Set.prototype.clear.call(process.allowedNodeEnvironmentFlags);
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);

process.allowedNodeEnvironmentFlags.delete('-r');
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
Set.prototype.delete.call(process.allowedNodeEnvironmentFlags, '-r');
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
}

0 comments on commit 6262973

Please sign in to comment.