From 9d24f71d45e8797c2bf161fe3bfab252f966b725 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Fri, 22 May 2020 14:04:51 +0200 Subject: [PATCH] console: mark special console properties as non-enumerable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure internal console properties are not visible during default inspection. They are still visible when inspecting the console with `showHidden` set to `true`. These properties are confusing while working with the REPL and easily show up. Signed-off-by: Ruben Bridgewater PR-URL: https://github.com/nodejs/node/pull/33524 Reviewed-By: Michaƫl Zasso Reviewed-By: James M Snell Reviewed-By: Anto Aravinth --- lib/internal/console/constructor.js | 276 +++++++++++++++------------- 1 file changed, 147 insertions(+), 129 deletions(-) diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index a6308c20369bb7..bdb8a84b94c4af 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -155,68 +155,156 @@ ObjectDefineProperty(Console, SymbolHasInstance, { } }); -// Eager version for the Console constructor -Console.prototype[kBindStreamsEager] = function(stdout, stderr) { - ObjectDefineProperties(this, { - '_stdout': { ...consolePropAttributes, value: stdout }, - '_stderr': { ...consolePropAttributes, value: stderr } - }); -}; +const kColorInspectOptions = { colors: true }; +const kNoColorInspectOptions = {}; -// Lazily load the stdout and stderr from an object so we don't -// create the stdio streams when they are not even accessed -Console.prototype[kBindStreamsLazy] = function(object) { - let stdout; - let stderr; - ObjectDefineProperties(this, { - '_stdout': { - enumerable: false, - configurable: true, - get() { - if (!stdout) stdout = object.stdout; - return stdout; - }, - set(value) { stdout = value; } - }, - '_stderr': { - enumerable: false, - configurable: true, - get() { - if (!stderr) { stderr = object.stderr; } - return stderr; - }, - set(value) { stderr = value; } +ObjectDefineProperties(Console.prototype, { + [kBindStreamsEager]: { + ...consolePropAttributes, + // Eager version for the Console constructor + value: function(stdout, stderr) { + ObjectDefineProperties(this, { + '_stdout': { ...consolePropAttributes, value: stdout }, + '_stderr': { ...consolePropAttributes, value: stderr } + }); } - }); -}; + }, + [kBindStreamsLazy]: { + ...consolePropAttributes, + // Lazily load the stdout and stderr from an object so we don't + // create the stdio streams when they are not even accessed + value: function(object) { + let stdout; + let stderr; + ObjectDefineProperties(this, { + '_stdout': { + enumerable: false, + configurable: true, + get() { + if (!stdout) stdout = object.stdout; + return stdout; + }, + set(value) { stdout = value; } + }, + '_stderr': { + enumerable: false, + configurable: true, + get() { + if (!stderr) { stderr = object.stderr; } + return stderr; + }, + set(value) { stderr = value; } + } + }); + } + }, + [kBindProperties]: { + ...consolePropAttributes, + value: function(ignoreErrors, colorMode, groupIndentation = 2) { + ObjectDefineProperties(this, { + '_stdoutErrorHandler': { + ...consolePropAttributes, + value: createWriteErrorHandler(this, kUseStdout) + }, + '_stderrErrorHandler': { + ...consolePropAttributes, + value: createWriteErrorHandler(this, kUseStderr) + }, + '_ignoreErrors': { + ...consolePropAttributes, + value: Boolean(ignoreErrors) + }, + '_times': { ...consolePropAttributes, value: new Map() }, + // Corresponds to https://console.spec.whatwg.org/#count-map + [kCounts]: { ...consolePropAttributes, value: new Map() }, + [kColorMode]: { ...consolePropAttributes, value: colorMode }, + [kIsConsole]: { ...consolePropAttributes, value: true }, + [kGroupIndent]: { ...consolePropAttributes, value: '' }, + [kGroupIndentationWidth]: { + ...consolePropAttributes, + value: groupIndentation + }, + }); + } + }, + [kWriteToConsole]: { + ...consolePropAttributes, + value: function(streamSymbol, string) { + const ignoreErrors = this._ignoreErrors; + const groupIndent = this[kGroupIndent]; + + const useStdout = streamSymbol === kUseStdout; + const stream = useStdout ? this._stdout : this._stderr; + const errorHandler = useStdout ? + this._stdoutErrorHandler : this._stderrErrorHandler; + + if (groupIndent.length !== 0) { + if (string.includes('\n')) { + string = string.replace(/\n/g, `\n${groupIndent}`); + } + string = groupIndent + string; + } + string += '\n'; + + if (ignoreErrors === false) return stream.write(string); + + // There may be an error occurring synchronously (e.g. for files or TTYs + // on POSIX systems) or asynchronously (e.g. pipes on POSIX systems), so + // handle both situations. + try { + // Add and later remove a noop error handler to catch synchronous + // errors. + if (stream.listenerCount('error') === 0) + stream.once('error', noop); + + stream.write(string, errorHandler); + } catch (e) { + // Console is a debugging utility, so it swallowing errors is not + // desirable even in edge cases such as low stack space. + if (isStackOverflowError(e)) + throw e; + // Sorry, there's no proper way to pass along the error here. + } finally { + stream.removeListener('error', noop); + } + } + }, + [kGetInspectOptions]: { + ...consolePropAttributes, + value: function(stream) { + let color = this[kColorMode]; + if (color === 'auto') { + color = stream.isTTY && ( + typeof stream.getColorDepth === 'function' ? + stream.getColorDepth() > 2 : true); + } -Console.prototype[kBindProperties] = function(ignoreErrors, colorMode, - groupIndentation = 2) { - ObjectDefineProperties(this, { - '_stdoutErrorHandler': { - ...consolePropAttributes, - value: createWriteErrorHandler(this, kUseStdout) - }, - '_stderrErrorHandler': { - ...consolePropAttributes, - value: createWriteErrorHandler(this, kUseStderr) - }, - '_ignoreErrors': { - ...consolePropAttributes, - value: Boolean(ignoreErrors) - }, - '_times': { ...consolePropAttributes, value: new Map() }, - // Corresponds to https://console.spec.whatwg.org/#count-map - [kCounts]: { ...consolePropAttributes, value: new Map() }, - [kColorMode]: { ...consolePropAttributes, value: colorMode }, - [kIsConsole]: { ...consolePropAttributes, value: true }, - [kGroupIndent]: { ...consolePropAttributes, value: '' }, - [kGroupIndentationWidth]: { - ...consolePropAttributes, - value: groupIndentation - }, - }); -}; + const options = optionsMap.get(this); + if (options) { + if (options.colors === undefined) { + options.colors = color; + } + return options; + } + + return color ? kColorInspectOptions : kNoColorInspectOptions; + } + }, + [kFormatForStdout]: { + ...consolePropAttributes, + value: function(args) { + const opts = this[kGetInspectOptions](this._stdout); + return formatWithOptions(opts, ...args); + } + }, + [kFormatForStderr]: { + ...consolePropAttributes, + value: function(args) { + const opts = this[kGetInspectOptions](this._stderr); + return formatWithOptions(opts, ...args); + } + }, +}); // Make a function that can serve as the callback passed to `stream.write()`. function createWriteErrorHandler(instance, streamSymbol) { @@ -239,76 +327,6 @@ function createWriteErrorHandler(instance, streamSymbol) { }; } -Console.prototype[kWriteToConsole] = function(streamSymbol, string) { - const ignoreErrors = this._ignoreErrors; - const groupIndent = this[kGroupIndent]; - - const useStdout = streamSymbol === kUseStdout; - const stream = useStdout ? this._stdout : this._stderr; - const errorHandler = useStdout ? - this._stdoutErrorHandler : this._stderrErrorHandler; - - if (groupIndent.length !== 0) { - if (string.includes('\n')) { - string = string.replace(/\n/g, `\n${groupIndent}`); - } - string = groupIndent + string; - } - string += '\n'; - - if (ignoreErrors === false) return stream.write(string); - - // There may be an error occurring synchronously (e.g. for files or TTYs - // on POSIX systems) or asynchronously (e.g. pipes on POSIX systems), so - // handle both situations. - try { - // Add and later remove a noop error handler to catch synchronous errors. - if (stream.listenerCount('error') === 0) - stream.once('error', noop); - - stream.write(string, errorHandler); - } catch (e) { - // Console is a debugging utility, so it swallowing errors is not desirable - // even in edge cases such as low stack space. - if (isStackOverflowError(e)) - throw e; - // Sorry, there's no proper way to pass along the error here. - } finally { - stream.removeListener('error', noop); - } -}; - -const kColorInspectOptions = { colors: true }; -const kNoColorInspectOptions = {}; -Console.prototype[kGetInspectOptions] = function(stream) { - let color = this[kColorMode]; - if (color === 'auto') { - color = stream.isTTY && ( - typeof stream.getColorDepth === 'function' ? - stream.getColorDepth() > 2 : true); - } - - const options = optionsMap.get(this); - if (options) { - if (options.colors === undefined) { - options.colors = color; - } - return options; - } - - return color ? kColorInspectOptions : kNoColorInspectOptions; -}; - -Console.prototype[kFormatForStdout] = function(args) { - const opts = this[kGetInspectOptions](this._stdout); - return formatWithOptions(opts, ...args); -}; - -Console.prototype[kFormatForStderr] = function(args) { - const opts = this[kGetInspectOptions](this._stderr); - return formatWithOptions(opts, ...args); -}; - const consoleMethods = { log(...args) { this[kWriteToConsole](kUseStdout, this[kFormatForStdout](args));