From caf9ae748b1324c34284b324f2951b91368ca840 Mon Sep 17 00:00:00 2001 From: "Sakthipriyan Vairamani (thefourtheye)" Date: Mon, 26 Dec 2016 16:42:09 +0530 Subject: [PATCH] lib,src: make constants not inherit from Object Make sure `constants` object and all the nested objects don't inherit from `Object.prototype` but from `null`. PR-URL: https://github.com/nodejs/node/pull/10458 Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel Reviewed-By: Colin Ihrig Reviewed-By: Brian White --- lib/fs.js | 4 ++-- lib/internal/process.js | 3 +-- src/node.cc | 2 ++ src/node_constants.cc | 19 ++++++++++++++++ test/parallel/test-binding-constants.js | 30 +++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-binding-constants.js diff --git a/lib/fs.js b/lib/fs.js index 8c92db957b4663..3d65b2efa00d0f 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1058,7 +1058,7 @@ fs.fchmodSync = function(fd, mode) { return binding.fchmod(fd, modeNum(mode)); }; -if (constants.hasOwnProperty('O_SYMLINK')) { +if (constants.O_SYMLINK !== undefined) { fs.lchmod = function(path, mode, callback) { callback = maybeCallback(callback); fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { @@ -1116,7 +1116,7 @@ fs.chmodSync = function(path, mode) { return binding.chmod(pathModule._makeLong(path), modeNum(mode)); }; -if (constants.hasOwnProperty('O_SYMLINK')) { +if (constants.O_SYMLINK !== undefined) { fs.lchown = function(path, uid, gid, callback) { callback = maybeCallback(callback); fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { diff --git a/lib/internal/process.js b/lib/internal/process.js index a53618fd373206..b4fe19093a82c1 100644 --- a/lib/internal/process.js +++ b/lib/internal/process.js @@ -201,8 +201,7 @@ function setupSignalHandlers() { const signalWraps = {}; function isSignal(event) { - return typeof event === 'string' && - lazyConstants().hasOwnProperty(event); + return typeof event === 'string' && lazyConstants()[event] !== undefined; } // Detect presence of a listener for the special signal types diff --git a/src/node.cc b/src/node.cc index d79b8ee30edd2b..52bf719852d891 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2673,6 +2673,8 @@ static void Binding(const FunctionCallbackInfo& args) { cache->Set(module, exports); } else if (!strcmp(*module_v, "constants")) { exports = Object::New(env->isolate()); + CHECK(exports->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); DefineConstants(env->isolate(), exports); cache->Set(module, exports); } else if (!strcmp(*module_v, "natives")) { diff --git a/src/node_constants.cc b/src/node_constants.cc index bed87b764980de..5bde53fcdf1ae5 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -1245,12 +1245,31 @@ void DefineZlibConstants(Local target) { } void DefineConstants(v8::Isolate* isolate, Local target) { + Environment* env = Environment::GetCurrent(isolate); + Local os_constants = Object::New(isolate); + CHECK(os_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); + Local err_constants = Object::New(isolate); + CHECK(err_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); + Local sig_constants = Object::New(isolate); + CHECK(sig_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); + Local fs_constants = Object::New(isolate); + CHECK(fs_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); + Local crypto_constants = Object::New(isolate); + CHECK(crypto_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); + Local zlib_constants = Object::New(isolate); + CHECK(zlib_constants->SetPrototype(env->context(), + Null(env->isolate())).FromJust()); DefineErrnoConstants(err_constants); DefineWindowsErrorConstants(err_constants); diff --git a/test/parallel/test-binding-constants.js b/test/parallel/test-binding-constants.js new file mode 100644 index 00000000000000..fcc95c21a3f7ea --- /dev/null +++ b/test/parallel/test-binding-constants.js @@ -0,0 +1,30 @@ +'use strict'; + +require('../common'); +const constants = process.binding('constants'); +const assert = require('assert'); + +assert.deepStrictEqual( + Object.keys(constants).sort(), ['crypto', 'fs', 'os', 'zlib'] +); + +assert.deepStrictEqual( + Object.keys(constants.os).sort(), ['UV_UDP_REUSEADDR', 'errno', 'signals'] +); + +// Make sure all the constants objects don't inherit from Object.prototype +const inheritedProperties = Object.getOwnPropertyNames(Object.prototype); +function test(obj) { + assert(obj); + assert.strictEqual(Object.prototype.toString.call(obj), '[object Object]'); + assert.strictEqual(Object.getPrototypeOf(obj), null); + + inheritedProperties.forEach((property) => { + assert.strictEqual(property in obj, false); + }); +} + +[ + constants, constants.crypto, constants.fs, constants.os, constants.zlib, + constants.os.errno, constants.os.signals +].forEach(test);