From f52598c97bcde40739fd83141806b92b1c186857 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Thu, 30 Jun 2022 12:18:02 +0200 Subject: [PATCH] process: make process.config read only --- lib/internal/bootstrap/node.js | 70 ++-------------------------- test/parallel/test-process-config.js | 10 ++++ 2 files changed, 14 insertions(+), 66 deletions(-) diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 0f72e3e67af306..92cc8c49a448eb 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -46,10 +46,8 @@ const { JSONParse, ObjectDefineProperty, ObjectGetPrototypeOf, - ObjectPreventExtensions, ObjectSetPrototypeOf, - ReflectGet, - ReflectSet, + ObjectFreeze, SymbolToStringTag, globalThis, } = primordials; @@ -72,75 +70,15 @@ process._exiting = false; // process.config is serialized config.gypi const nativeModule = internalBinding('native_module'); -// TODO(@jasnell): Once this has gone through one full major -// release cycle, remove the Proxy and setter and update the -// getter to either return a read-only object or always return -// a freshly parsed version of nativeModule.config. - -const deprecationHandler = { - warned: false, - message: 'Setting process.config is deprecated. ' + - 'In the future the property will be read-only.', - code: 'DEP0150', - maybeWarn() { - if (!this.warned) { - process.emitWarning(this.message, { - type: 'DeprecationWarning', - code: this.code - }); - this.warned = true; - } - }, - - defineProperty(target, key, descriptor) { - this.maybeWarn(); - return ObjectDefineProperty(target, key, descriptor); - }, - - deleteProperty(target, key) { - this.maybeWarn(); - delete target[key]; - }, - - preventExtensions(target) { - this.maybeWarn(); - return ObjectPreventExtensions(target); - }, - - set(target, key, value) { - this.maybeWarn(); - return ReflectSet(target, key, value); - }, - - get(target, key, receiver) { - const val = ReflectGet(target, key, receiver); - if (val != null && typeof val === 'object') { - // eslint-disable-next-line node-core/prefer-primordials - return new Proxy(val, deprecationHandler); - } - return val; - }, - - setPrototypeOf(target, proto) { - this.maybeWarn(); - return ObjectSetPrototypeOf(target, proto); - } -}; - -// eslint-disable-next-line node-core/prefer-primordials -let processConfig = new Proxy( - JSONParse(nativeModule.config), - deprecationHandler); +const processConfig = JSONParse(nativeModule.config, (_key, value) => { + return ObjectFreeze(value); +}) ObjectDefineProperty(process, 'config', { __proto__: null, enumerable: true, configurable: true, get() { return processConfig; }, - set(value) { - deprecationHandler.maybeWarn(); - processConfig = value; - } }); require('internal/worker/js_transferable').setup(); diff --git a/test/parallel/test-process-config.js b/test/parallel/test-process-config.js index a48e107d4c22a3..52b5ae6a031ec0 100644 --- a/test/parallel/test-process-config.js +++ b/test/parallel/test-process-config.js @@ -36,6 +36,16 @@ assert(Object.hasOwn(process, 'config')); // Ensure that `process.config` is an Object. assert.strictEqual(Object(process.config), process.config); +// Ensure that you can't change config values +try { + process.config.variables = 42; +} catch (e) { + assert.strictEqual( + e.message, + "Cannot assign to read only property 'variables' of object '#'" + ); +} + const configPath = path.resolve(__dirname, '..', '..', 'config.gypi'); if (!fs.existsSync(configPath)) {