Skip to content

Commit 96f3977

Browse files
committed
process: runtime deprecate changing process.config
The fact that `process.config` is mutable has long made it unreliable when it really should just work. Start the process of deprecating the ability to change it. Fixes: #7803 Signed-off-by: James M Snell <[email protected]> PR-URL: #36902 Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
1 parent a35b32e commit 96f3977

File tree

3 files changed

+94
-1
lines changed

3 files changed

+94
-1
lines changed

Diff for: doc/api/deprecations.md

+15
Original file line numberDiff line numberDiff line change
@@ -2711,6 +2711,21 @@ Type: Documentation-only.
27112711

27122712
Prefer [`message.socket`][] over [`message.connection`][].
27132713

2714+
### DEP0XXX: Changing the value of `process.config`
2715+
<!-- YAML
2716+
changes:
2717+
- version: REPLACEME
2718+
pr-url: https://github.com/nodejs/node/pull/36902
2719+
description: Runtime deprecation.
2720+
-->
2721+
2722+
Type: Runtime
2723+
2724+
The `process.config` property is intended to provide access to configuration
2725+
settings set when the Node.js binary was compiled. However, the property has
2726+
been mutable by user code making it impossible to rely on. The ability to
2727+
change the value has been deprecated and will be disabled in the future.
2728+
27142729
[Legacy URL API]: url.md#url_legacy_url_api
27152730
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
27162731
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3

Diff for: doc/api/process.md

+8
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,10 @@ This feature is not available in [`Worker`][] threads.
759759
## `process.config`
760760
<!-- YAML
761761
added: v0.7.7
762+
changes:
763+
- version: REPLACEME
764+
pr-url: https://github.com/nodejs/node/pull/36902
765+
description: Modifying process.config has been deprecated.
762766
-->
763767

764768
* {Object}
@@ -803,6 +807,10 @@ The `process.config` property is **not** read-only and there are existing
803807
modules in the ecosystem that are known to extend, modify, or entirely replace
804808
the value of `process.config`.
805809

810+
Modifying the `process.config` property, or any child-property of the
811+
`process.config` object has been deprecated. The `process.config` will be made
812+
read-only in a future release.
813+
806814
## `process.connected`
807815
<!-- YAML
808816
added: v0.7.2

Diff for: lib/internal/bootstrap/node.js

+71-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ const {
4343
JSONParse,
4444
ObjectDefineProperty,
4545
ObjectGetPrototypeOf,
46+
ObjectPreventExtensions,
4647
ObjectSetPrototypeOf,
48+
ReflectGet,
49+
ReflectSet,
4750
SymbolToStringTag,
4851
} = primordials;
4952
const config = internalBinding('config');
@@ -59,7 +62,74 @@ process._exiting = false;
5962

6063
// process.config is serialized config.gypi
6164
const nativeModule = internalBinding('native_module');
62-
process.config = JSONParse(nativeModule.config);
65+
66+
// TODO(@jasnell): Once this has gone through one full major
67+
// release cycle, remove the Proxy and setter and update the
68+
// getter to either return a read-only object or always return
69+
// a freshly parsed version of nativeModule.config.
70+
71+
const deprecationHandler = {
72+
warned: false,
73+
message: 'Setting process.config is deprecated. ' +
74+
'In the future the property will be read-only.',
75+
code: 'DEP0XXX',
76+
maybeWarn() {
77+
if (!this.warned) {
78+
process.emitWarning(this.message, {
79+
type: 'DeprecationWarning',
80+
code: this.code
81+
});
82+
this.warned = true;
83+
}
84+
},
85+
86+
defineProperty(target, key, descriptor) {
87+
this.maybeWarn();
88+
return ObjectDefineProperty(target, key, descriptor);
89+
},
90+
91+
deleteProperty(target, key) {
92+
this.maybeWarn();
93+
delete target[key];
94+
},
95+
96+
preventExtensions(target) {
97+
this.maybeWarn();
98+
return ObjectPreventExtensions(target);
99+
},
100+
101+
set(target, key, value) {
102+
this.maybeWarn();
103+
return ReflectSet(target, key, value);
104+
},
105+
106+
get(target, key, receiver) {
107+
const val = ReflectGet(target, key, receiver);
108+
if (val != null && typeof val === 'object')
109+
return new Proxy(val, deprecationHandler);
110+
return val;
111+
},
112+
113+
setPrototypeOf(target, proto) {
114+
this.maybeWarn();
115+
return ObjectSetPrototypeOf(target, proto);
116+
}
117+
};
118+
119+
let processConfig = new Proxy(
120+
JSONParse(nativeModule.config),
121+
deprecationHandler);
122+
123+
ObjectDefineProperty(process, 'config', {
124+
enumerable: true,
125+
configurable: true,
126+
get() { return processConfig; },
127+
set(value) {
128+
deprecationHandler.maybeWarn();
129+
processConfig = value;
130+
}
131+
});
132+
63133
require('internal/worker/js_transferable').setup();
64134

65135
// Bootstrappers for all threads, including worker threads and main thread

0 commit comments

Comments
 (0)