Skip to content

Commit 6262973

Browse files
committed
process: disallow adding options to process.allowedNodeEnvironmentFlags
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; ```
1 parent b5f5c46 commit 6262973

File tree

2 files changed

+73
-23
lines changed

2 files changed

+73
-23
lines changed

lib/internal/process/per_thread.js

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@
66

77
const {
88
ArrayPrototypeEvery,
9+
ArrayPrototypeIncludes,
910
ArrayPrototypeMap,
1011
ArrayPrototypePush,
1112
ArrayPrototypeSplice,
1213
BigUint64Array,
1314
Float64Array,
1415
NumberMAX_SAFE_INTEGER,
15-
ObjectDefineProperty,
1616
ObjectFreeze,
1717
ReflectApply,
1818
RegExpPrototypeTest,
19-
SafeSet,
19+
SafeArrayIterator,
20+
Set,
2021
StringPrototypeEndsWith,
2122
StringPrototypeReplace,
2223
StringPrototypeSlice,
2324
StringPrototypeStartsWith,
25+
Symbol,
26+
SymbolIterator,
2427
Uint32Array,
2528
} = primordials;
2629

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

47+
const kSet = Symbol('internal set');
48+
4449
function assert(x, msg) {
4550
if (!x) throw new ERR_ASSERTION(msg || 'assertion error');
4651
}
@@ -293,18 +298,18 @@ function buildAllowedFlags() {
293298

294299
// Save these for comparison against flags provided to
295300
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
296-
const nodeFlags = new SafeSet(ArrayPrototypeMap(allowedNodeEnvironmentFlags,
297-
trimLeadingDashes));
298-
299-
class NodeEnvironmentFlagsSet extends SafeSet {
300-
constructor(...args) {
301-
super(...args);
302-
303-
// The super constructor consumes `add`, but
304-
// disallow any future adds.
305-
ObjectDefineProperty(this, 'add', {
306-
value: () => this
307-
});
301+
const nodeFlags = ArrayPrototypeMap(allowedNodeEnvironmentFlags,
302+
trimLeadingDashes);
303+
304+
class NodeEnvironmentFlagsSet extends Set {
305+
constructor(iterable) {
306+
super();
307+
this[kSet] = new Set(new SafeArrayIterator(iterable));
308+
}
309+
310+
add() {
311+
// No-op, `Set` API compatible
312+
return this;
308313
}
309314

310315
delete() {
@@ -313,7 +318,7 @@ function buildAllowedFlags() {
313318
}
314319

315320
clear() {
316-
// No-op
321+
// No-op, `Set` API compatible
317322
}
318323

319324
has(key) {
@@ -328,13 +333,32 @@ function buildAllowedFlags() {
328333
key = StringPrototypeReplace(key, replaceUnderscoresRegex, '-');
329334
if (RegExpPrototypeTest(leadingDashesRegex, key)) {
330335
key = StringPrototypeReplace(key, trailingValuesRegex, '');
331-
return super.has(key);
336+
return this[kSet].has(key);
332337
}
333-
return nodeFlags.has(key);
338+
return ArrayPrototypeIncludes(nodeFlags, key);
334339
}
335340
return false;
336341
}
342+
343+
entries() {
344+
return this[kSet].entries();
345+
}
346+
347+
forEach(callback, thisArg = undefined) {
348+
this[kSet].forEach((v) => ReflectApply(callback, thisArg, [v, v, this]));
349+
}
350+
351+
get size() {
352+
return this[kSet].size;
353+
}
354+
355+
values() {
356+
return this[kSet].values();
357+
}
337358
}
359+
NodeEnvironmentFlagsSet.prototype.keys =
360+
NodeEnvironmentFlagsSet.prototype[SymbolIterator] =
361+
NodeEnvironmentFlagsSet.prototype.values;
338362

339363
ObjectFreeze(NodeEnvironmentFlagsSet.prototype.constructor);
340364
ObjectFreeze(NodeEnvironmentFlagsSet.prototype);

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

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
require('../common');
3+
const common = require('../common');
44
const assert = require('assert');
55

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

6464
process.allowedNodeEnvironmentFlags.add('foo');
65+
Set.prototype.add.call(process.allowedNodeEnvironmentFlags, 'foo');
6566
assert.strictEqual(process.allowedNodeEnvironmentFlags.has('foo'), false);
66-
process.allowedNodeEnvironmentFlags.forEach((flag) => {
67-
assert.strictEqual(flag === 'foo', false);
68-
});
6967

70-
process.allowedNodeEnvironmentFlags.clear();
71-
assert.strictEqual(process.allowedNodeEnvironmentFlags.size > 0, true);
68+
const thisArg = {};
69+
process.allowedNodeEnvironmentFlags.forEach(
70+
common.mustCallAtLeast(function(flag, _, set) {
71+
assert.notStrictEqual(flag, 'foo');
72+
assert.strictEqual(this, thisArg);
73+
assert.strictEqual(set, process.allowedNodeEnvironmentFlags);
74+
}),
75+
thisArg
76+
);
77+
78+
for (const flag of process.allowedNodeEnvironmentFlags.keys()) {
79+
assert.notStrictEqual(flag, 'foo');
80+
}
81+
for (const flag of process.allowedNodeEnvironmentFlags.values()) {
82+
assert.notStrictEqual(flag, 'foo');
83+
}
84+
for (const flag of process.allowedNodeEnvironmentFlags) {
85+
assert.notStrictEqual(flag, 'foo');
86+
}
87+
for (const [flag] of process.allowedNodeEnvironmentFlags.entries()) {
88+
assert.notStrictEqual(flag, 'foo');
89+
}
7290

7391
const size = process.allowedNodeEnvironmentFlags.size;
92+
93+
process.allowedNodeEnvironmentFlags.clear();
94+
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
95+
Set.prototype.clear.call(process.allowedNodeEnvironmentFlags);
96+
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
97+
7498
process.allowedNodeEnvironmentFlags.delete('-r');
7599
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
100+
Set.prototype.delete.call(process.allowedNodeEnvironmentFlags, '-r');
101+
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
76102
}

0 commit comments

Comments
 (0)