Skip to content

Commit 86874ce

Browse files
committed
process: make process.config read only
1 parent 49a5e81 commit 86874ce

File tree

5 files changed

+23
-80
lines changed

5 files changed

+23
-80
lines changed

doc/api/deprecations.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -2889,12 +2889,15 @@ Prefer [`message.socket`][] over [`message.connection`][].
28892889

28902890
<!-- YAML
28912891
changes:
2892+
- version: REPLACEME
2893+
pr-url: https://github.com/nodejs/node/pull/43627
2894+
description: End-of-Life.
28922895
- version: v16.0.0
28932896
pr-url: https://github.com/nodejs/node/pull/36902
28942897
description: Runtime deprecation.
28952898
-->
28962899

2897-
Type: Runtime
2900+
Type: End-of-Life
28982901

28992902
The `process.config` property provides access to Node.js compile-time settings.
29002903
However, the property is mutable and therefore subject to tampering. The ability

doc/api/process.md

+7-12
Original file line numberDiff line numberDiff line change
@@ -1041,17 +1041,20 @@ This feature is not available in [`Worker`][] threads.
10411041
<!-- YAML
10421042
added: v0.7.7
10431043
changes:
1044+
- version: REPLACEME
1045+
pr-url: https://github.com/nodejs/node/pull/43627
1046+
description: The `process.config` object is now frozen.
10441047
- version: v16.0.0
10451048
pr-url: https://github.com/nodejs/node/pull/36902
10461049
description: Modifying process.config has been deprecated.
10471050
-->
10481051

10491052
* {Object}
10501053

1051-
The `process.config` property returns an `Object` containing the JavaScript
1052-
representation of the configure options used to compile the current Node.js
1053-
executable. This is the same as the `config.gypi` file that was produced when
1054-
running the `./configure` script.
1054+
The `process.config` property returns a frozen `Object` containing the
1055+
JavaScript representation of the configure options used to compile the current
1056+
Node.js executable. This is the same as the `config.gypi` file that was produced
1057+
when running the `./configure` script.
10551058

10561059
An example of the possible output looks like:
10571060

@@ -1085,14 +1088,6 @@ An example of the possible output looks like:
10851088
}
10861089
```
10871090

1088-
The `process.config` property is **not** read-only and there are existing
1089-
modules in the ecosystem that are known to extend, modify, or entirely replace
1090-
the value of `process.config`.
1091-
1092-
Modifying the `process.config` property, or any child-property of the
1093-
`process.config` object has been deprecated. The `process.config` will be made
1094-
read-only in a future release.
1095-
10961091
## `process.connected`
10971092

10981093
<!-- YAML

lib/internal/bootstrap/node.js

+8-67
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,8 @@ const {
4646
JSONParse,
4747
ObjectDefineProperty,
4848
ObjectGetPrototypeOf,
49-
ObjectPreventExtensions,
5049
ObjectSetPrototypeOf,
51-
ReflectGet,
52-
ReflectSet,
50+
ObjectFreeze,
5351
SymbolToStringTag,
5452
globalThis,
5553
} = primordials;
@@ -72,75 +70,18 @@ process._exiting = false;
7270
// process.config is serialized config.gypi
7371
const nativeModule = internalBinding('native_module');
7472

75-
// TODO(@jasnell): Once this has gone through one full major
76-
// release cycle, remove the Proxy and setter and update the
77-
// getter to either return a read-only object or always return
78-
// a freshly parsed version of nativeModule.config.
79-
80-
const deprecationHandler = {
81-
warned: false,
82-
message: 'Setting process.config is deprecated. ' +
83-
'In the future the property will be read-only.',
84-
code: 'DEP0150',
85-
maybeWarn() {
86-
if (!this.warned) {
87-
process.emitWarning(this.message, {
88-
type: 'DeprecationWarning',
89-
code: this.code
90-
});
91-
this.warned = true;
92-
}
93-
},
94-
95-
defineProperty(target, key, descriptor) {
96-
this.maybeWarn();
97-
return ObjectDefineProperty(target, key, descriptor);
98-
},
99-
100-
deleteProperty(target, key) {
101-
this.maybeWarn();
102-
delete target[key];
103-
},
104-
105-
preventExtensions(target) {
106-
this.maybeWarn();
107-
return ObjectPreventExtensions(target);
108-
},
109-
110-
set(target, key, value) {
111-
this.maybeWarn();
112-
return ReflectSet(target, key, value);
113-
},
114-
115-
get(target, key, receiver) {
116-
const val = ReflectGet(target, key, receiver);
117-
if (val != null && typeof val === 'object') {
118-
// eslint-disable-next-line node-core/prefer-primordials
119-
return new Proxy(val, deprecationHandler);
120-
}
121-
return val;
122-
},
123-
124-
setPrototypeOf(target, proto) {
125-
this.maybeWarn();
126-
return ObjectSetPrototypeOf(target, proto);
127-
}
128-
};
129-
130-
// eslint-disable-next-line node-core/prefer-primordials
131-
let processConfig = new Proxy(
132-
JSONParse(nativeModule.config),
133-
deprecationHandler);
73+
const processConfig = JSONParse(nativeModule.config, (_key, value) => {
74+
// The `reviver` argument of the JSONParse method will visit all the values of
75+
// the parsed config, including the "root" object, so there is no need to
76+
// explicitly freeze the config outside of this method
77+
return ObjectFreeze(value);
78+
});
13479

13580
ObjectDefineProperty(process, 'config', {
13681
__proto__: null,
13782
enumerable: true,
13883
configurable: true,
139-
get() { return processConfig; },
140-
set(value) {
141-
deprecationHandler.maybeWarn();
142-
processConfig = value;
143-
}
84+
value: processConfig,
14485
});
14586

14687
require('internal/worker/js_transferable').setup();

test/fixtures/overwrite-config-preload-module.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
const common = require('../common');
33
common.skipIfInspectorDisabled();
44

5+
delete process.config;
56
process.config = {};

test/parallel/test-process-config.js

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ assert(Object.hasOwn(process, 'config'));
3636
// Ensure that `process.config` is an Object.
3737
assert.strictEqual(Object(process.config), process.config);
3838

39+
// Ensure that you can't change config values
40+
assert.throws(() => { process.config.variables = 42; }, TypeError);
41+
3942
const configPath = path.resolve(__dirname, '..', '..', 'config.gypi');
4043

4144
if (!fs.existsSync(configPath)) {

0 commit comments

Comments
 (0)