Skip to content

Commit f1753d4

Browse files
aduh95jasnell
authored andcommitted
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; ``` PR-URL: #36660 Reviewed-By: Darshan Sen <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent ee58b2d commit f1753d4

File tree

2 files changed

+84
-23
lines changed

2 files changed

+84
-23
lines changed

lib/internal/process/per_thread.js

+51-17
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,27 @@
66

77
const {
88
ArrayPrototypeEvery,
9+
ArrayPrototypeForEach,
10+
ArrayPrototypeIncludes,
911
ArrayPrototypeMap,
1012
ArrayPrototypePush,
1113
ArrayPrototypeSplice,
1214
BigUint64Array,
1315
Float64Array,
1416
NumberMAX_SAFE_INTEGER,
15-
ObjectDefineProperty,
1617
ObjectFreeze,
1718
ReflectApply,
1819
RegExpPrototypeTest,
19-
SafeSet,
20+
SafeArrayIterator,
21+
Set,
22+
SetPrototypeEntries,
23+
SetPrototypeValues,
2024
StringPrototypeEndsWith,
2125
StringPrototypeReplace,
2226
StringPrototypeSlice,
2327
StringPrototypeStartsWith,
28+
Symbol,
29+
SymbolIterator,
2430
Uint32Array,
2531
} = primordials;
2632

@@ -41,6 +47,8 @@ const {
4147
} = require('internal/validators');
4248
const constants = internalBinding('constants').os.signals;
4349

50+
const kInternal = Symbol('internal properties');
51+
4452
function assert(x, msg) {
4553
if (!x) throw new ERR_ASSERTION(msg || 'assertion error');
4654
}
@@ -293,18 +301,18 @@ function buildAllowedFlags() {
293301

294302
// Save these for comparison against flags provided to
295303
// 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-
});
304+
const nodeFlags = ArrayPrototypeMap(allowedNodeEnvironmentFlags,
305+
trimLeadingDashes);
306+
307+
class NodeEnvironmentFlagsSet extends Set {
308+
constructor(array) {
309+
super();
310+
this[kInternal] = { array };
311+
}
312+
313+
add() {
314+
// No-op, `Set` API compatible
315+
return this;
308316
}
309317

310318
delete() {
@@ -313,7 +321,7 @@ function buildAllowedFlags() {
313321
}
314322

315323
clear() {
316-
// No-op
324+
// No-op, `Set` API compatible
317325
}
318326

319327
has(key) {
@@ -328,13 +336,39 @@ function buildAllowedFlags() {
328336
key = StringPrototypeReplace(key, replaceUnderscoresRegex, '-');
329337
if (RegExpPrototypeTest(leadingDashesRegex, key)) {
330338
key = StringPrototypeReplace(key, trailingValuesRegex, '');
331-
return super.has(key);
339+
return ArrayPrototypeIncludes(this[kInternal].array, key);
332340
}
333-
return nodeFlags.has(key);
341+
return ArrayPrototypeIncludes(nodeFlags, key);
334342
}
335343
return false;
336344
}
345+
346+
entries() {
347+
this[kInternal].set ??=
348+
new Set(new SafeArrayIterator(this[kInternal].array));
349+
return SetPrototypeEntries(this[kInternal].set);
350+
}
351+
352+
forEach(callback, thisArg = undefined) {
353+
ArrayPrototypeForEach(
354+
this[kInternal].array,
355+
(v) => ReflectApply(callback, thisArg, [v, v, this])
356+
);
357+
}
358+
359+
get size() {
360+
return this[kInternal].array.length;
361+
}
362+
363+
values() {
364+
this[kInternal].set ??=
365+
new Set(new SafeArrayIterator(this[kInternal].array));
366+
return SetPrototypeValues(this[kInternal].set);
367+
}
337368
}
369+
NodeEnvironmentFlagsSet.prototype.keys =
370+
NodeEnvironmentFlagsSet.prototype[SymbolIterator] =
371+
NodeEnvironmentFlagsSet.prototype.values;
338372

339373
ObjectFreeze(NodeEnvironmentFlagsSet.prototype.constructor);
340374
ObjectFreeze(NodeEnvironmentFlagsSet.prototype);

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

+33-6
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
@@ -63,14 +63,41 @@ const assert = require('assert');
6363

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

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

7392
const size = process.allowedNodeEnvironmentFlags.size;
93+
94+
process.allowedNodeEnvironmentFlags.clear();
95+
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
96+
Set.prototype.clear.call(process.allowedNodeEnvironmentFlags);
97+
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
98+
7499
process.allowedNodeEnvironmentFlags.delete('-r');
75100
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
101+
Set.prototype.delete.call(process.allowedNodeEnvironmentFlags, '-r');
102+
assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size);
76103
}

0 commit comments

Comments
 (0)