assert: use stricter stack frame detection in .ifError()

This makes sure arbitrary stack traces are not handled as stack
frames.

Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de>

PR-URL: https://github.com/nodejs/node/pull/41006
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Ruben Bridgewater
2021-12-06 18:38:26 +01:00
committed by GitHub
parent 76372607a6
commit 414bc7bec1
2 changed files with 31 additions and 13 deletions

View File

@@ -966,21 +966,27 @@ assert.ifError = function ifError(err) {
// This will remove any duplicated frames from the error frames taken
// from within `ifError` and add the original error frames to the newly
// created ones.
const tmp2 = StringPrototypeSplit(origStack, '\n');
ArrayPrototypeShift(tmp2);
// Filter all frames existing in err.stack.
let tmp1 = StringPrototypeSplit(newErr.stack, '\n');
for (const errFrame of tmp2) {
// Find the first occurrence of the frame.
const pos = ArrayPrototypeIndexOf(tmp1, errFrame);
if (pos !== -1) {
// Only keep new frames.
tmp1 = ArrayPrototypeSlice(tmp1, 0, pos);
break;
const origStackStart = origStack.indexOf('\n at');
if (origStackStart !== -1) {
const originalFrames = StringPrototypeSplit(
origStack.slice(origStackStart + 1),
'\n'
);
// Filter all frames existing in err.stack.
let newFrames = StringPrototypeSplit(newErr.stack, '\n');
for (const errFrame of originalFrames) {
// Find the first occurrence of the frame.
const pos = ArrayPrototypeIndexOf(newFrames, errFrame);
if (pos !== -1) {
// Only keep new frames.
newFrames = ArrayPrototypeSlice(newFrames, 0, pos);
break;
}
}
const stackStart = ArrayPrototypeJoin(newFrames, '\n');
const stackEnd = ArrayPrototypeJoin(originalFrames, '\n');
newErr.stack = `${stackStart}\n${stackEnd}`;
}
newErr.stack =
`${ArrayPrototypeJoin(tmp1, '\n')}\n${ArrayPrototypeJoin(tmp2, '\n')}`;
}
throw newErr;

View File

@@ -39,6 +39,18 @@ const stack = err.stack;
})();
})();
assert.throws(
() => {
const error = new Error();
error.stack = 'Error: containing weird stack\nYes!\nI am part of a stack.';
assert.ifError(error);
},
(error) => {
assert(!error.stack.includes('Yes!'));
return true;
}
);
assert.throws(
() => assert.ifError(new TypeError()),
{