From 3875a7a3ff0d4ff1d498bb86dbddb62e5e93a6f8 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 18 Dec 2018 03:15:57 +0100 Subject: [PATCH 1/3] lib: remove internal `util._extends()` usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes all internal calls to the deprecated `_extends()` function. It is slower than `Object.assign()` and the object spread notation since V8 6.8 and using the spread notation often also results in shorter code. PR-URL: https://github.com/nodejs/node/pull/25105 Reviewed-By: Michaƫl Zasso Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Luigi Pinca --- lib/_http_agent.js | 8 +++----- lib/_http_client.js | 6 +++--- lib/_http_server.js | 2 +- lib/_tls_wrap.js | 18 ++++++++--------- lib/child_process.js | 35 ++++++++++++++++++---------------- lib/domain.js | 8 +++----- lib/fs.js | 18 ++++++++--------- lib/https.js | 11 ++++++----- lib/internal/cluster/child.js | 10 +++++----- lib/internal/cluster/master.js | 29 +++++++++++++--------------- lib/internal/cluster/utils.js | 4 +--- lib/internal/fs/utils.js | 2 +- lib/internal/repl.js | 7 ++++--- lib/internal/url.js | 11 ++++++----- lib/net.js | 2 +- lib/tty.js | 11 +++++------ lib/zlib.js | 3 +-- 17 files changed, 89 insertions(+), 96 deletions(-) diff --git a/lib/_http_agent.js b/lib/_http_agent.js index e3d307133864f4..17f6856bc703ad 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -48,7 +48,7 @@ function Agent(options) { this.defaultPort = 80; this.protocol = 'http:'; - this.options = util._extend({}, options); + this.options = { ...options }; // Don't confuse net and make it think that we're connecting to a pipe this.options.path = null; @@ -146,8 +146,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, }; } - options = util._extend({}, options); - util._extend(options, this.options); + options = { ...options, ...this.options }; if (options.socketPath) options.path = options.socketPath; @@ -194,8 +193,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, }; Agent.prototype.createSocket = function createSocket(req, options, cb) { - options = util._extend({}, options); - util._extend(options, this.options); + options = { ...options, ...this.options }; if (options.socketPath) options.path = options.socketPath; diff --git a/lib/_http_client.js b/lib/_http_client.js index 5dd75090361c7e..cbc406f5e8b8d0 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -93,11 +93,11 @@ function ClientRequest(input, options, cb) { if (typeof options === 'function') { cb = options; - options = null; + options = input || {}; + } else { + options = Object.assign(input || {}, options); } - options = util._extend(input || {}, options || {}); - var agent = options.agent; var defaultAgent = options._defaultAgent || Agent.globalAgent; if (agent === false) { diff --git a/lib/_http_server.js b/lib/_http_server.js index cfcaf9f34c2ca1..c0172ccf52d1d9 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -280,7 +280,7 @@ function Server(options, requestListener) { requestListener = options; options = {}; } else if (options == null || typeof options === 'object') { - options = util._extend({}, options); + options = { ...options }; } this[kIncomingMessage] = options.IncomingMessage || IncomingMessage; diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index cf08c58971b54e..8d59da1b866f65 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -1108,9 +1108,9 @@ function SNICallback(servername, callback) { // // function normalizeConnectArgs(listArgs) { - var args = net._normalizeArgs(listArgs); - var options = args[0]; - var cb = args[1]; + const args = net._normalizeArgs(listArgs); + const options = args[0]; + const cb = args[1]; // If args[0] was options, then normalize dealt with it. // If args[0] is port, or args[0], args[1] is host, port, we need to @@ -1118,12 +1118,12 @@ function normalizeConnectArgs(listArgs) { // the host/port/path args that it knows about, not the tls options. // This means that options.host overrides a host arg. if (listArgs[1] !== null && typeof listArgs[1] === 'object') { - util._extend(options, listArgs[1]); + Object.assign(options, listArgs[1]); } else if (listArgs[2] !== null && typeof listArgs[2] === 'object') { - util._extend(options, listArgs[2]); + Object.assign(options, listArgs[2]); } - return (cb) ? [options, cb] : [options]; + return cb ? [options, cb] : [options]; } function onConnectSecure() { @@ -1204,14 +1204,14 @@ exports.connect = function connect(...args) { 'certificate verification.'); } - var defaults = { + options = { rejectUnauthorized: !allowUnauthorized, ciphers: tls.DEFAULT_CIPHERS, checkServerIdentity: tls.checkServerIdentity, - minDHSize: 1024 + minDHSize: 1024, + ...options }; - options = util._extend(defaults, options || {}); if (!options.keepAlive) options.singleUse = true; diff --git a/lib/child_process.js b/lib/child_process.js index 108254f4a3c2b3..1a5411c8164c10 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -79,7 +79,7 @@ exports.fork = function fork(modulePath /* , args, options */) { throw new ERR_INVALID_ARG_VALUE(`arguments[${pos}]`, arguments[pos]); } - options = util._extend({}, arguments[pos++]); + options = { ...arguments[pos++] }; } // Prepare arguments for fork: @@ -176,20 +176,12 @@ Object.defineProperty(exports.exec, util.promisify.custom, { }); exports.execFile = function execFile(file /* , args, options, callback */) { - var args = []; - var callback; - var options = { - encoding: 'utf8', - timeout: 0, - maxBuffer: 200 * 1024, - killSignal: 'SIGTERM', - cwd: null, - env: null, - shell: false - }; + let args = []; + let callback; + let options; // Parse the optional positional parameters. - var pos = 1; + let pos = 1; if (pos < arguments.length && Array.isArray(arguments[pos])) { args = arguments[pos++]; } else if (pos < arguments.length && arguments[pos] == null) { @@ -197,7 +189,7 @@ exports.execFile = function execFile(file /* , args, options, callback */) { } if (pos < arguments.length && typeof arguments[pos] === 'object') { - util._extend(options, arguments[pos++]); + options = arguments[pos++]; } else if (pos < arguments.length && arguments[pos] == null) { pos++; } @@ -210,6 +202,17 @@ exports.execFile = function execFile(file /* , args, options, callback */) { throw new ERR_INVALID_ARG_VALUE('args', arguments[pos]); } + options = { + encoding: 'utf8', + timeout: 0, + maxBuffer: 200 * 1024, + killSignal: 'SIGTERM', + cwd: null, + env: null, + shell: false, + ...options + }; + // Validate the timeout, if present. validateTimeout(options.timeout); @@ -580,7 +583,7 @@ function spawnSync(file, args, options) { options.stdio = _validateStdio(options.stdio || 'pipe', true).stdio; if (options.input) { - var stdin = options.stdio[0] = util._extend({}, options.stdio[0]); + var stdin = options.stdio[0] = { ...options.stdio[0] }; stdin.input = options.input; } @@ -588,7 +591,7 @@ function spawnSync(file, args, options) { for (var i = 0; i < options.stdio.length; i++) { var input = options.stdio[i] && options.stdio[i].input; if (input != null) { - var pipe = options.stdio[i] = util._extend({}, options.stdio[i]); + var pipe = options.stdio[i] = { ...options.stdio[i] }; if (isArrayBufferView(input)) { pipe.input = input; } else if (typeof input === 'string') { diff --git a/lib/domain.js b/lib/domain.js index bd59a709298345..a60147b49eacbd 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -350,11 +350,9 @@ Domain.prototype.run = function(fn) { function intercepted(_this, self, cb, fnargs) { if (fnargs[0] && fnargs[0] instanceof Error) { var er = fnargs[0]; - util._extend(er, { - domainBound: cb, - domainThrown: false, - domain: self - }); + er.domainBound = cb; + er.domainThrown = false; + er.domain = self; self.emit('error', er); return; } diff --git a/lib/fs.js b/lib/fs.js index 57b3bed1e6e883..ad0a498e639521 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -39,7 +39,6 @@ const { O_SYMLINK } = constants; -const { _extend } = require('util'); const pathModule = require('path'); const { isArrayBufferView } = require('internal/util/types'); const binding = process.binding('fs'); @@ -1294,21 +1293,20 @@ function watchFile(filename, options, listener) { filename = pathModule.resolve(filename); let stat; - const defaults = { + if (options === null || typeof options !== 'object') { + listener = options; + options = null; + } + + options = { // Poll interval in milliseconds. 5007 is what libev used to use. It's // a little on the slow side but let's stick with it for now to keep // behavioral changes to a minimum. interval: 5007, - persistent: true + persistent: true, + ...options }; - if (options !== null && typeof options === 'object') { - options = _extend(defaults, options); - } else { - listener = options; - options = defaults; - } - if (typeof listener !== 'function') { throw new ERR_INVALID_ARG_TYPE('listener', 'Function', listener); } diff --git a/lib/https.js b/lib/https.js index 06b37c2143da9d..96111176994a25 100644 --- a/lib/https.js +++ b/lib/https.js @@ -46,7 +46,7 @@ function Server(opts, requestListener) { requestListener = opts; opts = undefined; } - opts = util._extend({}, opts); + opts = { ...opts }; if (!opts.ALPNProtocols) { // http/1.0 is not defined as Protocol IDs in IANA @@ -110,9 +110,10 @@ function createConnection(port, host, options) { const session = this._getSession(options._agentKey); if (session) { debug('reuse session for %j', options._agentKey); - options = util._extend({ - session: session - }, options); + options = { + session, + ...options + }; } } @@ -291,7 +292,7 @@ function request(...args) { } if (args[0] && typeof args[0] !== 'function') { - options = util._extend(options, args.shift()); + Object.assign(options, args.shift()); } options._defaultAgent = module.exports.globalAgent; diff --git a/lib/internal/cluster/child.js b/lib/internal/cluster/child.js index 13a22b0186fc28..272b0d2bd95008 100644 --- a/lib/internal/cluster/child.js +++ b/lib/internal/cluster/child.js @@ -1,6 +1,5 @@ 'use strict'; const assert = require('assert'); -const util = require('util'); const path = require('path'); const EventEmitter = require('events'); const { owner_symbol } = require('internal/async_hooks').symbols; @@ -71,11 +70,12 @@ cluster._getServer = function(obj, options, cb) { indexes.set(indexesKey, index); - const message = util._extend({ + const message = { act: 'queryServer', index, - data: null - }, options); + data: null, + ...options + }; message.address = address; @@ -151,7 +151,7 @@ function rr(message, indexesKey, cb) { function getsockname(out) { if (key) - util._extend(out, message.sockname); + Object.assign(out, message.sockname); return 0; } diff --git a/lib/internal/cluster/master.js b/lib/internal/cluster/master.js index 60083c6393e781..c4f8e2b0efa299 100644 --- a/lib/internal/cluster/master.js +++ b/lib/internal/cluster/master.js @@ -1,7 +1,6 @@ 'use strict'; const assert = require('assert'); const { fork } = require('child_process'); -const util = require('util'); const path = require('path'); const EventEmitter = require('events'); const RoundRobinHandle = require('internal/cluster/round_robin_handle'); @@ -47,14 +46,14 @@ if (schedulingPolicy === undefined) { cluster.schedulingPolicy = schedulingPolicy; cluster.setupMaster = function(options) { - var settings = { + const settings = { args: process.argv.slice(2), exec: process.argv[1], execArgv: process.execArgv, - silent: false + silent: false, + ...cluster.settings, + ...options }; - util._extend(settings, cluster.settings); - util._extend(settings, options || {}); // Tell V8 to write profile data for each process to a separate file. // Without --logfile=v8-%p.log, everything ends up in a single, unusable @@ -101,15 +100,12 @@ function setupSettingsNT(settings) { } function createWorkerProcess(id, env) { - const workerEnv = util._extend({}, process.env); + const workerEnv = { ...process.env, ...env, NODE_UNIQUE_ID: `${id}` }; const execArgv = cluster.settings.execArgv.slice(); const debugArgRegex = /--inspect(?:-brk|-port)?|--debug-port/; const nodeOptions = process.env.NODE_OPTIONS ? process.env.NODE_OPTIONS : ''; - util._extend(workerEnv, env); - workerEnv.NODE_UNIQUE_ID = '' + id; - if (execArgv.some((arg) => arg.match(debugArgRegex)) || nodeOptions.match(debugArgRegex)) { let inspectPort; @@ -315,17 +311,18 @@ function queryServer(worker, message) { // Set custom server data handle.add(worker, (errno, reply, handle) => { - reply = util._extend({ - errno: errno, - key: key, - ack: message.seq, - data: handles.get(key).data - }, reply); + const { data } = handles.get(key); if (errno) handles.delete(key); // Gives other workers a chance to retry. - send(worker, reply, handle); + send(worker, { + errno, + key, + ack: message.seq, + data, + ...reply + }, handle); }); } diff --git a/lib/internal/cluster/utils.js b/lib/internal/cluster/utils.js index 3fc5e408b76a5a..f20206c842be96 100644 --- a/lib/internal/cluster/utils.js +++ b/lib/internal/cluster/utils.js @@ -1,5 +1,4 @@ 'use strict'; -const util = require('util'); module.exports = { sendHelper, @@ -14,12 +13,11 @@ function sendHelper(proc, message, handle, cb) { return false; // Mark message as internal. See INTERNAL_PREFIX in lib/child_process.js - message = util._extend({ cmd: 'NODE_CLUSTER' }, message); + message = { cmd: 'NODE_CLUSTER', ...message, seq }; if (typeof cb === 'function') callbacks.set(seq, cb); - message.seq = seq; seq += 1; return proc.send(message, handle); } diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 4db4fb536c0b6a..0062bd435530d0 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -171,7 +171,7 @@ function getOptions(options, defaultOptions) { } if (typeof options === 'string') { - defaultOptions = util._extend({}, defaultOptions); + defaultOptions = { ...defaultOptions }; defaultOptions.encoding = options; options = defaultOptions; } else if (typeof options !== 'object') { diff --git a/lib/internal/repl.js b/lib/internal/repl.js index 4c4e3c8cb4e275..e58752e76eb890 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -24,12 +24,13 @@ function createRepl(env, opts, cb) { cb = opts; opts = null; } - opts = util._extend({ + opts = { ignoreUndefined: false, terminal: process.stdout.isTTY, useGlobal: true, - breakEvalOnSigint: true - }, opts); + breakEvalOnSigint: true, + ...opts + }; if (parseInt(env.NODE_NO_READLINE)) { opts.terminal = false; diff --git a/lib/internal/url.js b/lib/internal/url.js index 13063cb8f2f5a6..45ed236511ac9a 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -193,7 +193,7 @@ class URLSearchParams { return ctx.stylize('[Object]', 'special'); var separator = ', '; - var innerOpts = util._extend({}, ctx); + var innerOpts = { ...ctx }; if (recurseTimes !== null) { innerOpts.depth = recurseTimes - 1; } @@ -382,12 +382,13 @@ Object.defineProperties(URL.prototype, { value: function format(options) { if (options && typeof options !== 'object') throw new ERR_INVALID_ARG_TYPE('options', 'Object', options); - options = util._extend({ + options = { fragment: true, unicode: false, search: true, - auth: true - }, options); + auth: true, + ...options + }; const ctx = this[context]; var ret = ctx.scheme; if (ctx.host !== null) { @@ -1202,7 +1203,7 @@ defineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParams Iterator', { if (typeof recurseTimes === 'number' && recurseTimes < 0) return ctx.stylize('[Object]', 'special'); - const innerOpts = util._extend({}, ctx); + const innerOpts = { ...ctx }; if (recurseTimes !== null) { innerOpts.depth = recurseTimes - 1; } diff --git a/lib/net.js b/lib/net.js index eb5fae76fa17de..936dee088beb3f 100644 --- a/lib/net.js +++ b/lib/net.js @@ -245,7 +245,7 @@ function Socket(options) { if (typeof options === 'number') options = { fd: options }; // Legacy interface. else - options = util._extend({}, options); + options = { ...options }; options.readable = options.readable || false; options.writable = options.writable || false; diff --git a/lib/tty.js b/lib/tty.js index 62945a78eb1f0f..6efaac6e43215f 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -21,7 +21,7 @@ 'use strict'; -const { inherits, _extend } = require('util'); +const { inherits } = require('util'); const net = require('net'); const { TTY, isTTY } = internalBinding('tty_wrap'); const errors = require('internal/errors'); @@ -47,14 +47,13 @@ function ReadStream(fd, options) { throw new ERR_TTY_INIT_FAILED(ctx); } - options = _extend({ + net.Socket.call(this, { highWaterMark: 0, readable: true, writable: false, - handle: tty - }, options); - - net.Socket.call(this, options); + handle: tty, + ...options + }); this.isRaw = false; this.isTTY = true; diff --git a/lib/zlib.js b/lib/zlib.js index 49dcd4e92ecde4..2a840fe036abad 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -31,7 +31,6 @@ const { const Transform = require('_stream_transform'); const { deprecate, - _extend, inherits, types: { isAnyArrayBuffer, @@ -240,7 +239,7 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) { Z_NO_FLUSH, Z_BLOCK, finishFlush); if (opts.encoding || opts.objectMode || opts.writableObjectMode) { - opts = _extend({}, opts); + opts = { ...opts }; opts.encoding = null; opts.objectMode = false; opts.writableObjectMode = false; From 4788625d2963e22c60258e57646a5baa80920b45 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Thu, 20 Dec 2018 17:35:40 +0100 Subject: [PATCH 2/3] lib: expose all type checks from the internal types module Combine all type checks on the internal types module and do not use the types binding anywhere else anymore. This makes sure all of those checks exist when required. PR-URL: https://github.com/nodejs/node/pull/25149 Reviewed-By: Anna Henningsen Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Denys Otrishko --- lib/buffer.js | 2 +- lib/internal/bootstrap/node.js | 2 +- lib/internal/encoding.js | 7 +++---- lib/internal/util.js | 2 +- lib/internal/util/comparisons.js | 4 ++-- lib/internal/util/inspect.js | 14 +++++++------- lib/internal/util/types.js | 1 + lib/util.js | 12 +++--------- 8 files changed, 19 insertions(+), 25 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index 83deacd1fb0ce1..cf23f77ad72d0a 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -37,7 +37,6 @@ const { kMaxLength, kStringMaxLength } = internalBinding('buffer'); -const { isAnyArrayBuffer } = internalBinding('types'); const { customInspectSymbol, isInsideNodeModules, @@ -45,6 +44,7 @@ const { kIsEncodingSymbol } = require('internal/util'); const { + isAnyArrayBuffer, isArrayBufferView, isUint8Array } = require('internal/util/types'); diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index d7e8ff5016f763..5830055ce4bc80 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -179,7 +179,7 @@ // TODO(addaleax): Turn into a full runtime deprecation. const { pendingDeprecation } = internalBinding('config'); const utilBinding = internalBinding('util'); - const types = internalBinding('types'); + const types = NativeModule.require('internal/util/types'); for (const name of [ 'isArrayBuffer', 'isArrayBufferView', 'isAsyncFunction', 'isDataView', 'isDate', 'isExternal', 'isMap', 'isMapIterator', diff --git a/lib/internal/encoding.js b/lib/internal/encoding.js index ad056fd0bd997f..0084c19b904a82 100644 --- a/lib/internal/encoding.js +++ b/lib/internal/encoding.js @@ -21,11 +21,10 @@ const { customInspectSymbol: inspect } = require('internal/util'); -const { isArrayBufferView } = require('internal/util/types'); - const { - isArrayBuffer -} = internalBinding('types'); + isArrayBuffer, + isArrayBufferView +} = require('internal/util/types'); const { encodeUtf8String diff --git a/lib/internal/util.js b/lib/internal/util.js index 6929085d469676..fb3eed6f5e0dde 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -14,7 +14,7 @@ const { } = internalBinding('util'); const { isNativeError -} = internalBinding('types'); +} = require('internal/util/types'); const noCrypto = !process.versions.openssl; diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index 1d959f843bcbd3..d0726089063852 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -1,9 +1,9 @@ 'use strict'; const { compare } = internalBinding('buffer'); -const { isArrayBufferView } = require('internal/util/types'); const { isAnyArrayBuffer, + isArrayBufferView, isDate, isMap, isRegExp, @@ -15,7 +15,7 @@ const { isBooleanObject, isBigIntObject, isSymbolObject -} = internalBinding('types'); +} = require('internal/util/types'); const { getOwnNonIndexProperties, propertyFilter: { diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 4697829fba2756..2ef6b97d5686f2 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -27,8 +27,6 @@ const { isStackOverflowError } = require('internal/errors'); -const types = internalBinding('types'); -Object.assign(types, require('internal/util/types')); const { isAnyArrayBuffer, isArrayBuffer, @@ -38,6 +36,8 @@ const { isExternal, isMap, isMapIterator, + isModuleNamespaceObject, + isNativeError, isPromise, isSet, isSetIterator, @@ -61,7 +61,7 @@ const { isFloat64Array, isBigInt64Array, isBigUint64Array -} = types; +} = require('internal/util/types'); const ReflectApply = Reflect.apply; @@ -385,9 +385,9 @@ function getKeys(value, showHidden) { try { keys = Object.keys(value); } catch (err) { - if (types.isNativeError(err) && + if (isNativeError(err) && err.name === 'ReferenceError' && - types.isModuleNamespaceObject(value)) { + isModuleNamespaceObject(value)) { keys = Object.getOwnPropertyNames(value); } else { throw err; @@ -696,7 +696,7 @@ function formatRaw(ctx, value, recurseTimes) { } else if (isWeakMap(value)) { braces[0] = `${getPrefix(constructor, tag, 'WeakMap')}{`; formatter = ctx.showHidden ? formatWeakMap : formatWeakCollection; - } else if (types.isModuleNamespaceObject(value)) { + } else if (isModuleNamespaceObject(value)) { braces[0] = `[${tag}] {`; formatter = formatNamespaceObject; skip = true; @@ -883,7 +883,7 @@ function formatNamespaceObject(ctx, value, recurseTimes, keys) { output[i] = formatProperty(ctx, value, recurseTimes, keys[i], kObjectType); } catch (err) { - if (!(types.isNativeError(err) && err.name === 'ReferenceError')) { + if (!(isNativeError(err) && err.name === 'ReferenceError')) { throw err; } // Use the existing functionality. This makes sure the indentation and diff --git a/lib/internal/util/types.js b/lib/internal/util/types.js index 182625a9716c72..865818c661b78d 100644 --- a/lib/internal/util/types.js +++ b/lib/internal/util/types.js @@ -70,6 +70,7 @@ function isBigUint64Array(value) { } module.exports = { + ...internalBinding('types'), isArrayBufferView, isTypedArray, isUint8Array, diff --git a/lib/util.js b/lib/util.js index 06ce842934505a..624f4dfb7d032b 100644 --- a/lib/util.js +++ b/lib/util.js @@ -31,13 +31,7 @@ const { const { validateNumber } = require('internal/validators'); const { TextDecoder, TextEncoder } = require('internal/encoding'); const { isBuffer } = require('buffer').Buffer; - -const types = internalBinding('types'); -Object.assign(types, require('internal/util/types')); -const { - isRegExp, - isDate, -} = types; +const types = require('internal/util/types'); const { deprecate, @@ -433,9 +427,9 @@ module.exports = exports = { isString, isSymbol, isUndefined, - isRegExp, + isRegExp: types.isRegExp, isObject, - isDate, + isDate: types.isDate, isError(e) { return objectToString(e) === '[object Error]' || e instanceof Error; }, From 6e183847571f77ad5c5b9e9e95a20bda5a12e7a5 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Thu, 20 Dec 2018 03:43:02 +0100 Subject: [PATCH 3/3] buffer: inspect extra properties This makes sure extra properties on buffers are not ignored anymore when inspecting the buffer. PR-URL: https://github.com/nodejs/node/pull/25150 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- lib/buffer.js | 24 +++++++++++++++++++++++- lib/internal/util/inspect.js | 4 +++- test/parallel/test-buffer-inspect.js | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index cf23f77ad72d0a..78bbbe0b73505a 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -37,6 +37,13 @@ const { kMaxLength, kStringMaxLength } = internalBinding('buffer'); +const { + getOwnNonIndexProperties, + propertyFilter: { + ALL_PROPERTIES, + ONLY_ENUMERABLE + } +} = internalBinding('util'); const { customInspectSymbol, isInsideNodeModules, @@ -51,6 +58,11 @@ const { const { pendingDeprecation } = internalBinding('config'); +const { + formatProperty, + kObjectType +} = require('internal/util/inspect'); + const { ERR_BUFFER_OUT_OF_BOUNDS, ERR_OUT_OF_RANGE, @@ -670,10 +682,20 @@ Buffer.prototype.equals = function equals(otherBuffer) { Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) { const max = exports.INSPECT_MAX_BYTES; const actualMax = Math.min(max, this.length); - let str = this.hexSlice(0, actualMax).replace(/(.{2})/g, '$1 ').trim(); const remaining = this.length - max; + let str = this.hexSlice(0, actualMax).replace(/(.{2})/g, '$1 ').trim(); if (remaining > 0) str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`; + // Inspect special properties as well, if possible. + if (ctx) { + const filter = ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE; + str += getOwnNonIndexProperties(this, filter).reduce((str, key) => { + // Using `formatProperty()` expects an indentationLvl to be set. + ctx.indentationLvl = 0; + str += `, ${formatProperty(ctx, this, recurseTimes, key, kObjectType)}`; + return str; + }, ''); + } return `<${this.constructor.name} ${str}>`; }; Buffer.prototype.inspect = Buffer.prototype[customInspectSymbol]; diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 2ef6b97d5686f2..b23ae9438ff877 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1220,5 +1220,7 @@ function reduceToSingleString(ctx, output, base, braces) { } module.exports = { - inspect + inspect, + formatProperty, + kObjectType }; diff --git a/test/parallel/test-buffer-inspect.js b/test/parallel/test-buffer-inspect.js index 9f91de700c7878..9230d7b089dd16 100644 --- a/test/parallel/test-buffer-inspect.js +++ b/test/parallel/test-buffer-inspect.js @@ -55,4 +55,4 @@ assert.strictEqual(util.inspect(b), expected); assert.strictEqual(util.inspect(s), expected); b.inspect = undefined; -assert.strictEqual(util.inspect(b), expected); +assert.strictEqual(util.inspect(b), '');