From 8fe5c23ac48dbc3715ae53d293ad2bacd218cb6b Mon Sep 17 00:00:00 2001 From: Chen Yangjian <252317+dotnil@users.noreply.github.com> Date: Thu, 24 Jan 2019 11:21:09 +0800 Subject: [PATCH] fix regex in utils.stackTraceFilter to prevent ReDoS #3416 if the stack trace begins with a large error message (>= 20k charactors), and user leaves `--full-trace` disabled, `utils.stackTraceFilter()` takes ages to finish. Large error messages is quite possible when user makes containment assertions such as `expect(content).to.contain(word)`. --- lib/utils.js | 4 +--- test/unit/runner.spec.js | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index fc0aa640fd..dbda3062db 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -647,8 +647,6 @@ exports.stackTraceFilter = function() { function isMochaInternal(line) { return ( ~line.indexOf('node_modules' + slash + 'mocha' + slash) || - ~line.indexOf('node_modules' + slash + 'mocha.js') || - ~line.indexOf('bower_components' + slash + 'mocha.js') || ~line.indexOf(slash + 'mocha.js') ); } @@ -677,7 +675,7 @@ exports.stackTraceFilter = function() { } // Clean up cwd(absolute) - if (/\(?.+:\d+:\d+\)?$/.test(line)) { + if (/:\d+:\d+\)?$/.test(line)) { line = line.replace('(' + cwd, '('); } diff --git a/test/unit/runner.spec.js b/test/unit/runner.spec.js index e89ef2b2d6..f13f09df47 100644 --- a/test/unit/runner.spec.js +++ b/test/unit/runner.spec.js @@ -487,6 +487,32 @@ describe('Runner', function() { }); runner.failHook(hook, err); }); + + it('should not hang if the error message is ridiculously long', function(done) { + var hook = new Hook(); + var message = []; + // mock a long message + for (var i = 0; i < 40000; i++) { + var line = stack[i % stack.length]; + message[i] = line[Math.floor(Math.random() * line.length)]; + } + var err = new Error(); + // Fake stack-trace + err.stack = [message.join('')].concat(stack).join('\n'); + + runner.on('fail', function(hook, err) { + expect( + err.stack + .split('\n') + .slice(1) + .join('\n'), + 'to be', + stack.slice(0, 3).join('\n') + ); + done(); + }); + runner.failHook(hook, err); + }); }); });