Skip to content

Commit

Permalink
util: inspect: do not crash on an Error with a regex name
Browse files Browse the repository at this point in the history
See #56570
  • Loading branch information
ljharb committed Jan 15, 2025
1 parent 2570f95 commit 73c0e96
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
17 changes: 14 additions & 3 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const {
StringPrototypePadEnd,
StringPrototypePadStart,
StringPrototypeRepeat,
StringPrototypeReplace,
StringPrototypeReplaceAll,
StringPrototypeSlice,
StringPrototypeSplit,
Expand Down Expand Up @@ -733,6 +734,7 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, output) {
} while (++depth !== 3);
}

/** @type {(constructor: string, tag: string, fallback: string, size?: string) => string} */
function getPrefix(constructor, tag, fallback, size = '') {
if (constructor === null) {
if (tag !== '' && fallback !== tag) {
Expand Down Expand Up @@ -1316,11 +1318,20 @@ function getStackFrames(ctx, err, stack) {
return frames;
}

/** @type {(stack: string, constructor: string | null, name: unknown, tag: string) => string} */
function improveStack(stack, constructor, name, tag) {
// A stack trace may contain arbitrary data. Only manipulate the output
// for "regular errors" (errors that "look normal") for now.
let len = name.length;

if (typeof name !== 'string') {
stack = StringPrototypeReplace(
stack,
`${name}`,
`${name} [${StringPrototypeSlice(getPrefix(constructor, tag, 'Error'), 0, -1)}]`,
);
}

if (constructor === null ||
(StringPrototypeEndsWith(name, 'Error') &&
StringPrototypeStartsWith(stack, name) &&
Expand Down Expand Up @@ -1353,8 +1364,8 @@ function removeDuplicateErrorKeys(ctx, keys, err, stack) {
if (!ctx.showHidden && keys.length !== 0) {
for (const name of ['name', 'message', 'stack']) {
const index = ArrayPrototypeIndexOf(keys, name);
// Only hide the property in case it's part of the original stack
if (index !== -1 && StringPrototypeIncludes(stack, err[name])) {
// Only hide the property if it's a string and if it's part of the original stack
if (index !== -1 && (typeof err[name] !== 'string' || StringPrototypeIncludes(stack, err[name]))) {
ArrayPrototypeSplice(keys, index, 1);
}
}
Expand Down Expand Up @@ -1414,7 +1425,7 @@ function safeGetCWD() {
}

function formatError(err, constructor, tag, ctx, keys) {
const name = err.name != null ? String(err.name) : 'Error';
const name = err.name != null ? err.name : 'Error';
let stack = getStackString(err);

removeDuplicateErrorKeys(ctx, keys, err, stack);
Expand Down
22 changes: 17 additions & 5 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -770,14 +770,14 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324');
// Note: Symbols are not supported by `Error#toString()` which is called by
// accessing the `stack` property.
[
[404, '404: foo', '[404]'],
[0, '0: foo', '[RangeError: foo]'],
[0n, '0: foo', '[RangeError: foo]'],
[404, '404 [RangeError]: foo', '[404]'],
[0, '0 [RangeError]: foo', '[RangeError: foo]'],
[0n, '0 [RangeError]: foo', '[RangeError: foo]'],
[null, 'null: foo', '[RangeError: foo]'],
[undefined, 'RangeError: foo', '[RangeError: foo]'],
[false, 'false: foo', '[RangeError: foo]'],
[false, 'false [RangeError]: foo', '[RangeError: foo]'],
['', 'foo', '[RangeError: foo]'],
[[1, 2, 3], '1,2,3: foo', '[1,2,3]'],
[[1, 2, 3], '1,2,3 [RangeError]: foo', '[1,2,3]'],
].forEach(([value, outputStart, stack]) => {
let err = new RangeError('foo');
err.name = value;
Expand Down Expand Up @@ -3436,3 +3436,15 @@ assert.strictEqual(
'[Function: Symbol(f)]',
);
}

{
const error = new EvalError();
const re = /a/g;
error.name = re;
assert.strictEqual(error.name, re);
assert.strictEqual(
util.inspect(error),
`${re} [EvalError]
${error.stack.split('\n').slice(1).join('\n')}`,
);

Check failure on line 3449 in test/parallel/test-util-inspect.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected indentation of 2 spaces but found 0
}

0 comments on commit 73c0e96

Please sign in to comment.