Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/console.js17
-rw-r--r--lib/internal/errors.js22
-rw-r--r--test/parallel/test-console-no-swallow-stack-overflow.js18
3 files changed, 45 insertions, 12 deletions
diff --git a/lib/console.js b/lib/console.js
index b77832b9876..d70a6b30b72 100644
--- a/lib/console.js
+++ b/lib/console.js
@@ -21,15 +21,16 @@
'use strict';
-const { ERR_CONSOLE_WRITABLE_STREAM } = require('internal/errors').codes;
+const {
+ isStackOverflowError,
+ codes: { ERR_CONSOLE_WRITABLE_STREAM },
+} = require('internal/errors');
const util = require('util');
const kCounts = Symbol('counts');
// Track amount of indentation required via `console.group()`.
const kGroupIndent = Symbol('groupIndent');
-let MAX_STACK_MESSAGE;
-
function Console(stdout, stderr, ignoreErrors = true) {
if (!(this instanceof Console)) {
return new Console(stdout, stderr, ignoreErrors);
@@ -113,17 +114,9 @@ function write(ignoreErrors, stream, string, errorhandler, groupIndent) {
stream.write(string, errorhandler);
} catch (e) {
- if (MAX_STACK_MESSAGE === undefined) {
- try {
- // eslint-disable-next-line no-unused-vars
- function a() { a(); }
- } catch (err) {
- MAX_STACK_MESSAGE = err.message;
- }
- }
// console is a debugging utility, so it swallowing errors is not desirable
// even in edge cases such as low stack space.
- if (e.message === MAX_STACK_MESSAGE && e.name === 'RangeError')
+ if (isStackOverflowError(e))
throw e;
// Sorry, there's no proper way to pass along the error here.
} finally {
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index a8c4bfb3c33..16b4cd2416f 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -569,11 +569,33 @@ function dnsException(err, syscall, hostname) {
return ex;
}
+let MAX_STACK_MESSAGE;
+/**
+ * Returns true if `err` is a `RangeError` with an engine-specific message.
+ * "Maximum call stack size exceeded" in V8.
+ *
+ * @param {Error} err
+ * @returns {boolean}
+ */
+function isStackOverflowError(err) {
+ if (MAX_STACK_MESSAGE === undefined) {
+ try {
+ function overflowStack() { overflowStack(); }
+ overflowStack();
+ } catch (err) {
+ MAX_STACK_MESSAGE = err.message;
+ }
+ }
+
+ return err.name === 'RangeError' && err.message === MAX_STACK_MESSAGE;
+}
+
module.exports = exports = {
dnsException,
errnoException,
exceptionWithHostPort,
uvException,
+ isStackOverflowError,
message,
AssertionError,
SystemError,
diff --git a/test/parallel/test-console-no-swallow-stack-overflow.js b/test/parallel/test-console-no-swallow-stack-overflow.js
new file mode 100644
index 00000000000..f36ba4857e3
--- /dev/null
+++ b/test/parallel/test-console-no-swallow-stack-overflow.js
@@ -0,0 +1,18 @@
+'use strict';
+const common = require('../common');
+const { Console } = require('console');
+const { Writable } = require('stream');
+
+for (const method of ['dir', 'log', 'warn']) {
+ common.expectsError(() => {
+ const out = new Writable({
+ write: common.mustCall(function write(...args) {
+ // Exceeds call stack.
+ return write(...args);
+ }),
+ });
+ const c = new Console(out, out, true);
+
+ c[method]('Hello, world!');
+ }, { name: 'RangeError' });
+}